biz-a-cli 2.3.79-15211 → 2.3.79-15212
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { io } from "socket.io-client";
|
|
2
|
+
import { workerEvents, workerStats } from "../worker/cliWorkerPool.js";
|
|
3
|
+
|
|
4
|
+
export class CLI_Agent {
|
|
5
|
+
constructor(dispatcherUrl, services = "ALL") {
|
|
6
|
+
const url = dispatcherUrl.startsWith("http")
|
|
7
|
+
? dispatcherUrl
|
|
8
|
+
: `http://${dispatcherUrl}`;
|
|
9
|
+
|
|
10
|
+
this.services = services.split(",").map((s) => s.trim().toUpperCase());
|
|
11
|
+
|
|
12
|
+
console.log(`[CLI Agent] Connecting to Message Broker at ${url}...`);
|
|
13
|
+
|
|
14
|
+
this.socketBus = io(`${url}/message-broker`, {
|
|
15
|
+
reconnectionDelay: 5000,
|
|
16
|
+
reconnectionDelayMax: 10000,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
this.socketBus.on("connect", () => {
|
|
20
|
+
console.log(
|
|
21
|
+
`[CLI Agent] Successfully connected. Listening for triggers...`,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
// 1. Register Capabilities
|
|
25
|
+
this.socketBus.emit("ESB_AGENT_REGISTER", {
|
|
26
|
+
services: this.services,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// 2. The Workload Heartbeat
|
|
30
|
+
if (this.statsInterval) clearInterval(this.statsInterval);
|
|
31
|
+
this.statsInterval = setInterval(() => {
|
|
32
|
+
const stats = workerStats();
|
|
33
|
+
const active = stats.cliScript
|
|
34
|
+
? stats.cliScript.activeTasks
|
|
35
|
+
: 0;
|
|
36
|
+
const pending = stats.cliScript
|
|
37
|
+
? stats.cliScript.pendingTasks
|
|
38
|
+
: 0;
|
|
39
|
+
this.socketBus.emit("ESB_AGENT_STATS", {
|
|
40
|
+
activeTasks: active + pending,
|
|
41
|
+
});
|
|
42
|
+
}, 2000);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
this.socketBus.on("disconnect", () => {
|
|
46
|
+
if (this.statsInterval) clearInterval(this.statsInterval);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// 3. Strict Upstream Routing
|
|
50
|
+
workerEvents.on("IPC_RELAY", (topic, payload) => {
|
|
51
|
+
this.socketBus.emit("ESB_UPSTREAM_RELAY", { topic, payload });
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
on(eventName, callback) {
|
|
56
|
+
this.socketBus.on(eventName, callback);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
publish(topic, payload = null, ackCallback = null) {
|
|
60
|
+
this.socketBus.emit(topic, payload, ackCallback);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import { workerEvents } from "../worker/cliWorkerPool.js";
|
|
3
|
+
|
|
4
|
+
export class CLI_Dispatcher {
|
|
5
|
+
constructor(mode, ioServerInstance = null) {
|
|
6
|
+
this.mode = mode || "monolithic";
|
|
7
|
+
this.agentRegistry = new Map(); // The Scoreboard
|
|
8
|
+
|
|
9
|
+
if (this.mode === "monolithic") {
|
|
10
|
+
this.localBus = new EventEmitter();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
console.log(`[Message Broker] Initialized in '${this.mode}' mode.`);
|
|
14
|
+
|
|
15
|
+
if (this.mode === "dispatcher" && ioServerInstance) {
|
|
16
|
+
this.agentNamespace = ioServerInstance.of("/message-broker");
|
|
17
|
+
|
|
18
|
+
this.agentNamespace.on("connection", (socket) => {
|
|
19
|
+
console.log(
|
|
20
|
+
`[Message Broker] Remote Agent connected: ${socket.id}`,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
this.agentRegistry.set(socket.id, {
|
|
24
|
+
activeTasks: 0,
|
|
25
|
+
services: [],
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
socket.on("ESB_AGENT_REGISTER", (data) => {
|
|
29
|
+
if (this.agentRegistry.has(socket.id)) {
|
|
30
|
+
this.agentRegistry.get(socket.id).services =
|
|
31
|
+
data.services || [];
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
socket.on("ESB_AGENT_STATS", (data) => {
|
|
36
|
+
if (this.agentRegistry.has(socket.id)) {
|
|
37
|
+
this.agentRegistry.get(socket.id).activeTasks =
|
|
38
|
+
data.activeTasks || 0;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
socket.on("ESB_UPSTREAM_RELAY", ({ topic, payload }) => {
|
|
43
|
+
this.balanceAndDispatchEvent(topic, payload);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
socket.on("disconnect", () => {
|
|
47
|
+
console.log(
|
|
48
|
+
`[Message Broker] Remote Agent disconnected: ${socket.id}`,
|
|
49
|
+
);
|
|
50
|
+
this.agentRegistry.delete(socket.id);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
workerEvents.on("IPC_RELAY", (topic, payload) => {
|
|
56
|
+
this.balanceAndDispatchEvent(topic, payload);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
balanceAndDispatchEvent(topic, payload) {
|
|
61
|
+
// --- EMIT TO SPECIFIC BIZ-A CLIENT ---
|
|
62
|
+
// ex: this.lib.emitClient(scriptData.clientSockId, scriptData.eventUUIDName, { status: "Done!" });
|
|
63
|
+
if (topic === "emitClient") {
|
|
64
|
+
console.log(
|
|
65
|
+
`\n[Future Dev] Target: Biz-A Client Socket ID [${payload?.clientSockId}]`,
|
|
66
|
+
);
|
|
67
|
+
console.log(`[Future Dev] Event: ${payload?.eventUUIDName}`);
|
|
68
|
+
console.log(`[Future Dev] Payload:`, payload?.payload, `\n`);
|
|
69
|
+
// TODO: this.agentNamespace.to(payload.clientSockId).emit(payload.eventUUIDName, payload.payload);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// --- EMIT TO ALL BIZ-A CLIENT ---
|
|
74
|
+
// ex: this.lib.broadcastClient("ui:alert", { message: "System maintenance in 5 mins" });
|
|
75
|
+
if (topic === "broadcastClient") {
|
|
76
|
+
console.log(`\n[Future Dev] Broadcast: ALL Clients in CLIENT_ROOM`);
|
|
77
|
+
console.log(`[Future Dev] Event: ${payload?.topic}`);
|
|
78
|
+
console.log(`[Future Dev] Payload:`, payload?.payload, `\n`);
|
|
79
|
+
// TODO: this.agentNamespace.to("clientRoom").emit(payload.topic, payload.payload);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// --- INTERNAL SYSTEM ROUTING ---
|
|
84
|
+
// ex : this.lib.emitCLI("email:send", data);
|
|
85
|
+
if (this.mode === "monolithic" && this.localBus) {
|
|
86
|
+
this.localBus.emit(topic, payload);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// --- ROUTING TO BEST AGENT (based on workload at each agent) ---
|
|
91
|
+
if (this.mode === "dispatcher" && this.agentNamespace) {
|
|
92
|
+
const requiredService = topic.split(":")[0].toUpperCase();
|
|
93
|
+
let bestAgentId = null;
|
|
94
|
+
let minTasks = Infinity;
|
|
95
|
+
|
|
96
|
+
for (const [socketId, stats] of this.agentRegistry.entries()) {
|
|
97
|
+
const canHandle =
|
|
98
|
+
stats.services.includes("ALL") ||
|
|
99
|
+
stats.services.includes(requiredService);
|
|
100
|
+
if (canHandle && stats.activeTasks < minTasks) {
|
|
101
|
+
minTasks = stats.activeTasks;
|
|
102
|
+
bestAgentId = socketId;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (bestAgentId) {
|
|
107
|
+
console.log(
|
|
108
|
+
`[Load Balancer] Routing '${topic}' to Agent ${bestAgentId} (Active Tasks: ${minTasks})`,
|
|
109
|
+
);
|
|
110
|
+
this.agentNamespace.to(bestAgentId).emit(topic, payload);
|
|
111
|
+
} else {
|
|
112
|
+
console.error(
|
|
113
|
+
`[Load Balancer] WARNING: No connected Agent supports '${requiredService}'`,
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
start(intervalMs = 5000) {
|
|
120
|
+
setInterval(() => {
|
|
121
|
+
this.publish("sys:tick");
|
|
122
|
+
}, intervalMs);
|
|
123
|
+
this.publish("sys:tick");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
on(eventName, callback) {
|
|
127
|
+
if (this.localBus) this.localBus.on(eventName, callback);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
publish(topic, payload = null, ackCallback = null) {
|
|
131
|
+
if (this.mode === "monolithic" && this.localBus) {
|
|
132
|
+
this.localBus.emit(topic, payload, ackCallback);
|
|
133
|
+
} else if (this.mode === "dispatcher" && this.agentNamespace) {
|
|
134
|
+
this.agentNamespace.emit(topic, payload, ackCallback);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CLI_Dispatcher } from "./dispatcher.js";
|
|
2
|
+
import { CLI_Agent } from "./agent.js";
|
|
3
|
+
import { initBpmAgent } from "../engine/bpm/bpm-agent.js";
|
|
4
|
+
|
|
5
|
+
export function bootMicroservices(argv, ioServerInstance = null) {
|
|
6
|
+
const services = argv.services || "ALL";
|
|
7
|
+
|
|
8
|
+
if (argv.mode === "monolithic") {
|
|
9
|
+
const broker = new CLI_Dispatcher("monolithic");
|
|
10
|
+
initBpmAgent(broker, "ALL");
|
|
11
|
+
broker.start(5000);
|
|
12
|
+
return broker;
|
|
13
|
+
} else if (argv.mode === "dispatcher") {
|
|
14
|
+
const broker = new CLI_Dispatcher("dispatcher", ioServerInstance);
|
|
15
|
+
initBpmAgent(broker, services);
|
|
16
|
+
broker.start(5000);
|
|
17
|
+
return broker;
|
|
18
|
+
} else if (argv.mode === "agent") {
|
|
19
|
+
const genericAgent = new CLI_Agent(argv.server, services);
|
|
20
|
+
initBpmAgent(genericAgent, services);
|
|
21
|
+
return genericAgent;
|
|
22
|
+
}
|
|
23
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "biz-a-cli",
|
|
3
|
-
"version": "2.3.79-
|
|
3
|
+
"version": "2.3.79-15212",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "bin/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"engine/**/*",
|
|
15
15
|
"envs/**/*",
|
|
16
16
|
"key/**/*",
|
|
17
|
+
"message-broker/**/*",
|
|
17
18
|
"migrations/**/*",
|
|
18
19
|
"scheduler/**/*",
|
|
19
20
|
"worker/**/*",
|