index.js
5.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/**
* Agent Registry — 四维配置版
*
* 职责:
* 1. 从 DB 加载所有 Agent/Client/Group/Settings 配置
* 2. 内存缓存 + 提供同步查询接口
* 3. 动态注册/注销 Agent(写 DB + 更新缓存)
* 4. 发出 registered/unregistered 事件
*/
const { EventEmitter } = require('events');
const agentQueries = require('../../../services/agent-queries');
class AgentRegistry extends EventEmitter {
constructor() {
super();
this._agents = {}; // name → agentConfig
this._clients = {}; // name → clientConfig
this._groups = {}; // name → groupConfig
this._settings = {};
this._loaded = false;
}
/**
* 从 DB 加载所有配置到内存
*/
async load() {
const fullConfig = await agentQueries.getFullConfig();
this._agents = fullConfig.agents || {};
this._clients = fullConfig.clients || {};
this._groups = fullConfig.agentGroups || {};
this._settings = fullConfig.settings || {};
this._loaded = true;
console.log(`[Registry] 已从 DB 加载 ${Object.keys(this._agents).length} 个 Agent, ${Object.keys(this._clients).length} 个 Client`);
}
// ═══════════════════════════════════════════════════════════
// Agent 查询
// ═══════════════════════════════════════════════════════════
/**
* 获取单个 Agent 配置 + 关联的 Client
* @returns {{ agent: object, client: object|null } | null}
*/
getAgent(name) {
const agent = this._agents[name];
if (!agent) return null;
const client = agent.client ? this._clients[agent.client] || null : null;
return { agent, client };
}
/**
* 列出所有 Agent
* @returns {Array<{ name, type, description, client, deploy, mode }>}
*/
listAgents() {
return Object.entries(this._agents).map(([name, cfg]) => ({
name,
type: cfg.type,
description: cfg.description,
client: cfg.client,
deploy: cfg.deploy,
}));
}
// ═══════════════════════════════════════════════════════════
// Client 查询
// ═══════════════════════════════════════════════════════════
/**
* 获取单个 Client 配置
*/
getClient(name) {
return this._clients[name] || null;
}
/**
* 列出所有 Client(完整配置)
*/
listClients() {
return Object.values(this._clients);
}
// ═══════════════════════════════════════════════════════════
// 配置汇总
// ═══════════════════════════════════════════════════════════
getGroups() {
return this._groups;
}
getSettings() {
return this._settings;
}
getFullConfig() {
return {
agents: this._agents,
clients: this._clients,
agentGroups: this._groups,
settings: this._settings,
};
}
// ═══════════════════════════════════════════════════════════
// 动态注册 / 注销
// ═══════════════════════════════════════════════════════════
/**
* 动态注册 Agent(写 DB + 更新缓存 + 触发事件)
*/
async register(name, config) {
if (this._agents[name]) {
throw new Error(`Agent "${name}" 已存在`);
}
await agentQueries.createAgent(name, config);
await this.load(); // 重新加载以确保一致性
console.log(`[Registry] 注册: ${name} (${config.type})`);
this.emit('registered', { name, config: this._agents[name] });
}
/**
* 动态注销 Agent(写 DB + 更新缓存 + 触发事件)
*/
async unregister(name) {
if (!this._agents[name]) {
throw new Error(`Agent "${name}" 不存在`);
}
const deleted = await agentQueries.deleteAgent(name);
if (!deleted) throw new Error(`删除 Agent "${name}" 失败`);
await this.load(); // 重新加载
console.log(`[Registry] 注销: ${name}`);
this.emit('unregistered', { name });
}
// ═══════════════════════════════════════════════════════════
// 缓存管理
// ═══════════════════════════════════════════════════════════
invalidateCache() {
this._loaded = false;
}
get loaded() {
return this._loaded;
}
// ═══════════════════════════════════════════════════════════
// 生命周期(兼容旧接口,空操作)
// ═══════════════════════════════════════════════════════════
startWatch() { /* DB 模式不需要文件监听 */ }
stopWatch() { /* DB 模式不需要文件监听 */ }
dispose() { this.removeAllListeners(); }
}
module.exports = { AgentRegistry };