@alfe.ai/gateway 0.10.4 → 0.10.5
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/health.js +41 -0
- package/package.json +2 -2
package/dist/health.js
CHANGED
|
@@ -7633,9 +7633,13 @@ async function stopExistingDaemon() {
|
|
|
7633
7633
|
* Each connected plugin registers with its name/version and receives
|
|
7634
7634
|
* commands from the daemon (forwarded from cloud).
|
|
7635
7635
|
*/
|
|
7636
|
+
/** Same-PID re-registrations inside this window before the flap warning fires. */
|
|
7637
|
+
const SAME_PID_FLAP_WINDOW_MS = 6e4;
|
|
7636
7638
|
var IPCServer = class {
|
|
7637
7639
|
server = null;
|
|
7638
7640
|
connections = /* @__PURE__ */ new Map();
|
|
7641
|
+
samePidReplacements = /* @__PURE__ */ new Map();
|
|
7642
|
+
samePidFlapWarnedAt = /* @__PURE__ */ new Map();
|
|
7639
7643
|
socketPath;
|
|
7640
7644
|
requestHandler = null;
|
|
7641
7645
|
constructor(socketPath, daemonVersion = "unknown") {
|
|
@@ -7696,6 +7700,8 @@ var IPCServer = class {
|
|
|
7696
7700
|
});
|
|
7697
7701
|
for (const conn of this.connections.values()) conn.socket.destroy();
|
|
7698
7702
|
this.connections.clear();
|
|
7703
|
+
this.samePidReplacements.clear();
|
|
7704
|
+
this.samePidFlapWarnedAt.clear();
|
|
7699
7705
|
});
|
|
7700
7706
|
}
|
|
7701
7707
|
/**
|
|
@@ -7871,6 +7877,40 @@ var IPCServer = class {
|
|
|
7871
7877
|
}, "IPC: unhandled message");
|
|
7872
7878
|
}
|
|
7873
7879
|
}
|
|
7880
|
+
/**
|
|
7881
|
+
* A plugin that keeps re-registering from the SAME process is two live
|
|
7882
|
+
* clients in one process evicting each other (two module instances of
|
|
7883
|
+
* the plugin, each with its own socket), not a reconnect after a fault.
|
|
7884
|
+
* Each eviction fails every request in flight on the evicted socket, so
|
|
7885
|
+
* the symptom downstream is "Connection closed" on any call longer than
|
|
7886
|
+
* the client's reconnect backoff (Wibke Jnr, 2026-09-21: 2 evictions/s,
|
|
7887
|
+
* every per-business MYOB call dead). The dedupe above is still right
|
|
7888
|
+
* (a genuinely stale socket must be dropped), so make the flap loud
|
|
7889
|
+
* instead: one warning per plugin per minute once it exceeds the rate.
|
|
7890
|
+
*/
|
|
7891
|
+
noteSamePidReplacement(name, pid) {
|
|
7892
|
+
const key = `${name}:${String(pid)}`;
|
|
7893
|
+
const now = Date.now();
|
|
7894
|
+
for (const [k, ts] of this.samePidReplacements) {
|
|
7895
|
+
if (k === key) continue;
|
|
7896
|
+
if (now - (ts[ts.length - 1] ?? 0) >= 6e4) {
|
|
7897
|
+
this.samePidReplacements.delete(k);
|
|
7898
|
+
this.samePidFlapWarnedAt.delete(k);
|
|
7899
|
+
}
|
|
7900
|
+
}
|
|
7901
|
+
const times = (this.samePidReplacements.get(key) ?? []).filter((t) => now - t < SAME_PID_FLAP_WINDOW_MS);
|
|
7902
|
+
times.push(now);
|
|
7903
|
+
this.samePidReplacements.set(key, times);
|
|
7904
|
+
if (times.length < 10) return;
|
|
7905
|
+
if (now - (this.samePidFlapWarnedAt.get(key) ?? 0) < 6e4) return;
|
|
7906
|
+
this.samePidFlapWarnedAt.set(key, now);
|
|
7907
|
+
logger.warn({
|
|
7908
|
+
plugin: name,
|
|
7909
|
+
pid,
|
|
7910
|
+
replacements: times.length,
|
|
7911
|
+
windowMs: SAME_PID_FLAP_WINDOW_MS
|
|
7912
|
+
}, "IPC: plugin is re-registering from the same process in a loop — two IPC clients in one process are evicting each other; in-flight requests fail with \"Connection closed\"");
|
|
7913
|
+
}
|
|
7874
7914
|
closeOversizedConnection(conn) {
|
|
7875
7915
|
logger.warn({
|
|
7876
7916
|
connId: conn.id,
|
|
@@ -7923,6 +7963,7 @@ var IPCServer = class {
|
|
|
7923
7963
|
plugin: name,
|
|
7924
7964
|
pid
|
|
7925
7965
|
}, "IPC: closing stale duplicate connection (same PID)");
|
|
7966
|
+
this.noteSamePidReplacement(name, pid);
|
|
7926
7967
|
existing.socket.destroy();
|
|
7927
7968
|
staleIds.push(existingId);
|
|
7928
7969
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfe.ai/gateway",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.5",
|
|
4
4
|
"description": "Alfe local gateway daemon — persistent control plane for agent integrations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"@alfe.ai/ai-proxy-local": "^0.0.17",
|
|
28
28
|
"@alfe.ai/config": "^0.4.1",
|
|
29
29
|
"@alfe.ai/integration-manifest": "^0.4.2",
|
|
30
|
-
"@alfe.ai/integrations": "^0.6.
|
|
30
|
+
"@alfe.ai/integrations": "^0.6.11",
|
|
31
31
|
"@alfe.ai/mcp-bundler": "^0.4.2"
|
|
32
32
|
},
|
|
33
33
|
"license": "UNLICENSED",
|