@melaya/runner 1.1.45 → 1.1.46
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 +36 -2
- package/package.json +1 -1
package/dist/connection.js
CHANGED
|
@@ -78,6 +78,27 @@ export async function connect(opts) {
|
|
|
78
78
|
reconnectionAttempts: Infinity,
|
|
79
79
|
});
|
|
80
80
|
let relay = null;
|
|
81
|
+
// ── Disconnect diagnostics (transport-close root-cause) ──────────────
|
|
82
|
+
// A "transport close" disconnect can be a NETWORK blip OR the Node event loop
|
|
83
|
+
// being BLOCKED (e.g. relaying big browser screenshots/trees) long enough that
|
|
84
|
+
// Socket.IO can't service the connection. These need OPPOSITE fixes, so we
|
|
85
|
+
// sample event-loop lag continuously and print the recent PEAK on disconnect:
|
|
86
|
+
// a multi-second spike ⇒ event-loop block (in-process work); ~0 ⇒ network/proxy.
|
|
87
|
+
let connectedAt = 0;
|
|
88
|
+
let lastHeartbeatAt = 0;
|
|
89
|
+
let peakLagMs = 0;
|
|
90
|
+
{
|
|
91
|
+
let last = Date.now();
|
|
92
|
+
const TICK = 500;
|
|
93
|
+
const t = setInterval(() => {
|
|
94
|
+
const now = Date.now();
|
|
95
|
+
const lag = now - last - TICK; // how much longer than TICK the loop actually took
|
|
96
|
+
last = now;
|
|
97
|
+
if (lag > peakLagMs)
|
|
98
|
+
peakLagMs = lag;
|
|
99
|
+
}, TICK);
|
|
100
|
+
t.unref?.();
|
|
101
|
+
}
|
|
81
102
|
// ── Melaya Browser bridge state (plan Sections 3/4) ──────────────────
|
|
82
103
|
// The governed browser control bridge is started lazily on the first
|
|
83
104
|
// browser run. Grant public keys arrive over the socket (server push)
|
|
@@ -209,6 +230,8 @@ export async function connect(opts) {
|
|
|
209
230
|
};
|
|
210
231
|
socket.on("connect", async () => {
|
|
211
232
|
spinner.succeed(chalk.green("Connected to Melaya"));
|
|
233
|
+
connectedAt = Date.now();
|
|
234
|
+
peakLagMs = 0; // fresh window each connection so the disconnect line reflects THIS session
|
|
212
235
|
// New socket lifetime → new generation. Grants minted for an earlier
|
|
213
236
|
// generation are refused (plan Section 4). Any browser runs from the
|
|
214
237
|
// previous connection are already torn down on the disconnect path.
|
|
@@ -269,7 +292,16 @@ export async function connect(opts) {
|
|
|
269
292
|
}
|
|
270
293
|
});
|
|
271
294
|
socket.on("disconnect", (reason) => {
|
|
272
|
-
|
|
295
|
+
const upS = connectedAt ? Math.round((Date.now() - connectedAt) / 1000) : 0;
|
|
296
|
+
const hbS = lastHeartbeatAt ? Math.round((Date.now() - lastHeartbeatAt) / 1000) : -1;
|
|
297
|
+
console.log(chalk.yellow(`\n Disconnected: ${reason} (up ${upS}s, last heartbeat ${hbS}s ago, peak event-loop lag ${peakLagMs}ms)`));
|
|
298
|
+
// The discriminator: a big peak lag (or a stale heartbeat) means the Node
|
|
299
|
+
// event loop was BLOCKED while connected — heavy in-process work (big browser
|
|
300
|
+
// screenshot/tree relay), NOT a network drop → fix is to offload/chunk that
|
|
301
|
+
// work. A small lag with "transport close" points at the network/proxy path.
|
|
302
|
+
if (peakLagMs > 2000 || hbS > 45) {
|
|
303
|
+
console.log(chalk.yellow(` ↳ event loop was blocked ~${peakLagMs}ms (heartbeat ${hbS}s ago) — this is in-process backpressure (likely big browser payload relay), not a network drop.`));
|
|
304
|
+
}
|
|
273
305
|
// Melaya Browser: a dropped socket invalidates every browser grant
|
|
274
306
|
// bound to this socket generation. Tear down ALL browser runs
|
|
275
307
|
// (cancels in-flight ops, releases leases, closes owned browsers);
|
|
@@ -430,8 +462,10 @@ export async function connect(opts) {
|
|
|
430
462
|
});
|
|
431
463
|
// ── Heartbeat ──────────────────────────────────────────────────────
|
|
432
464
|
setInterval(() => {
|
|
433
|
-
if (socket.connected)
|
|
465
|
+
if (socket.connected) {
|
|
434
466
|
socket.emit("runner:heartbeat");
|
|
467
|
+
lastHeartbeatAt = Date.now();
|
|
468
|
+
}
|
|
435
469
|
}, HEARTBEAT_INTERVAL);
|
|
436
470
|
// ── Run command ────────────────────────────────────────────────────
|
|
437
471
|
socket.on("runner:run", async (payload) => {
|