@melaya/runner 1.0.11 → 1.0.13
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.
- package/dist/connection.js +6 -3
- package/dist/localRelay.js +37 -5
- package/package.json +1 -1
package/dist/connection.js
CHANGED
|
@@ -133,15 +133,18 @@ export async function connect(opts) {
|
|
|
133
133
|
proc.on("exit", (code) => {
|
|
134
134
|
activeProcesses.delete(payload.runId);
|
|
135
135
|
const status = code === 0 ? "done" : "failed";
|
|
136
|
-
|
|
137
|
-
// Also emit a pushEvent so the frontend clears the LIVE state
|
|
138
|
-
// (runner:runComplete only updates the DB, it doesn't broadcast)
|
|
136
|
+
// Emit run_status FIRST (before runComplete deletes from ownedRunIds)
|
|
139
137
|
socket.emit("runner:event", {
|
|
140
138
|
run_id: payload.runId,
|
|
141
139
|
event_type: "run_status",
|
|
142
140
|
status,
|
|
143
141
|
project: payload.project,
|
|
144
142
|
});
|
|
143
|
+
// Small delay so the server processes run_status before runComplete
|
|
144
|
+
// removes the runId from ownedRunIds
|
|
145
|
+
setTimeout(() => {
|
|
146
|
+
socket.emit("runner:runComplete", { runId: payload.runId, status });
|
|
147
|
+
}, 200);
|
|
145
148
|
console.log(chalk.gray(` ■ Pipeline finished (exit ${code})\n`));
|
|
146
149
|
console.log(chalk.gray(" Waiting for pipeline runs...\n"));
|
|
147
150
|
});
|
package/dist/localRelay.js
CHANGED
|
@@ -13,6 +13,30 @@ import crypto from "crypto";
|
|
|
13
13
|
import http from "http";
|
|
14
14
|
let _activeProject = null;
|
|
15
15
|
export function setActiveProject(project) { _activeProject = project; }
|
|
16
|
+
// Throttle: batch events per 100ms to avoid per-token socket flood
|
|
17
|
+
const THROTTLE_MS = 100;
|
|
18
|
+
let _throttleTimer = null;
|
|
19
|
+
let _throttleQueue = [];
|
|
20
|
+
function _flushThrottle(socket, verbose) {
|
|
21
|
+
if (_throttleQueue.length === 0)
|
|
22
|
+
return;
|
|
23
|
+
// Send the LAST event per replyId (most recent content wins)
|
|
24
|
+
const byReply = new Map();
|
|
25
|
+
for (const p of _throttleQueue) {
|
|
26
|
+
const key = p.replyId || p.run_id || "default";
|
|
27
|
+
byReply.set(key, p);
|
|
28
|
+
}
|
|
29
|
+
for (const payload of byReply.values()) {
|
|
30
|
+
socket.emit("runner:event", payload);
|
|
31
|
+
if (verbose) {
|
|
32
|
+
const type = payload.event_type || "unknown";
|
|
33
|
+
const agent = payload.replyName || "";
|
|
34
|
+
process.stdout.write(` [relay] ${type}${agent ? ` (${agent})` : ""}\n`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
_throttleQueue = [];
|
|
38
|
+
_throttleTimer = null;
|
|
39
|
+
}
|
|
16
40
|
export function startLocalRelay(socket, verbose) {
|
|
17
41
|
const nonce = crypto.randomUUID().replace(/-/g, "");
|
|
18
42
|
return new Promise((resolve, reject) => {
|
|
@@ -30,11 +54,19 @@ export function startLocalRelay(socket, verbose) {
|
|
|
30
54
|
const payload = JSON.parse(body);
|
|
31
55
|
if (_activeProject && !payload.project)
|
|
32
56
|
payload.project = _activeProject;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
57
|
+
// Non-throttled events: run_status, pipeline_phase (critical lifecycle)
|
|
58
|
+
const et = payload.event_type;
|
|
59
|
+
if (et === "run_status" || et === "pipeline_phase") {
|
|
60
|
+
socket.emit("runner:event", payload);
|
|
61
|
+
if (verbose)
|
|
62
|
+
process.stdout.write(` [relay] ${et}\n`);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// Throttle agent_message events (100ms batching)
|
|
66
|
+
_throttleQueue.push(payload);
|
|
67
|
+
if (!_throttleTimer) {
|
|
68
|
+
_throttleTimer = setTimeout(() => _flushThrottle(socket, verbose), THROTTLE_MS);
|
|
69
|
+
}
|
|
38
70
|
}
|
|
39
71
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
40
72
|
res.end('{"relayed":true}');
|