@songsid/agend 2.1.2-beta.1 → 2.1.2-beta.3
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/backend/codex.d.ts +15 -0
- package/dist/backend/codex.js +223 -56
- package/dist/backend/codex.js.map +1 -1
- package/dist/channel/ipc-bridge.d.ts +8 -0
- package/dist/channel/ipc-bridge.js +41 -14
- package/dist/channel/ipc-bridge.js.map +1 -1
- package/dist/fleet-manager.d.ts +6 -0
- package/dist/fleet-manager.js +46 -6
- package/dist/fleet-manager.js.map +1 -1
- package/package.json +1 -1
package/dist/fleet-manager.js
CHANGED
|
@@ -163,6 +163,10 @@ export class FleetManager {
|
|
|
163
163
|
failoverActive = new Map(); // instance → current failover model
|
|
164
164
|
// IPC reconnect: tracks instances being intentionally stopped (skip reconnect)
|
|
165
165
|
ipcStoppingInstances = new Set();
|
|
166
|
+
/** Coalesce concurrent connection attempts for the same daemon socket. */
|
|
167
|
+
ipcConnectInFlight = new Map();
|
|
168
|
+
/** At most one reconnect/backoff loop may exist per instance. */
|
|
169
|
+
ipcReconnectInFlight = new Map();
|
|
166
170
|
// Adapter restart: prevents re-entrant restart attempts
|
|
167
171
|
adapterRestarting = new Set();
|
|
168
172
|
// Adapter isolation: track state per adapter for retry + visibility
|
|
@@ -1931,19 +1935,38 @@ export class FleetManager {
|
|
|
1931
1935
|
this.logger.info({ adapterId, type: channelConfig.type }, "Additional adapter started");
|
|
1932
1936
|
}
|
|
1933
1937
|
/** Connect IPC to a single instance with all handlers */
|
|
1934
|
-
|
|
1938
|
+
connectIpcToInstance(name) {
|
|
1939
|
+
const inFlight = this.ipcConnectInFlight.get(name);
|
|
1940
|
+
if (inFlight)
|
|
1941
|
+
return inFlight;
|
|
1942
|
+
const connection = this.connectIpcToInstanceInternal(name)
|
|
1943
|
+
.finally(() => {
|
|
1944
|
+
if (this.ipcConnectInFlight.get(name) === connection) {
|
|
1945
|
+
this.ipcConnectInFlight.delete(name);
|
|
1946
|
+
}
|
|
1947
|
+
});
|
|
1948
|
+
this.ipcConnectInFlight.set(name, connection);
|
|
1949
|
+
return connection;
|
|
1950
|
+
}
|
|
1951
|
+
async connectIpcToInstanceInternal(name) {
|
|
1935
1952
|
// Close existing client to prevent socket leak on reconnect
|
|
1936
1953
|
const existing = this.instanceIpcClients.get(name);
|
|
1937
1954
|
if (existing) {
|
|
1938
|
-
|
|
1955
|
+
// Remove application listeners before destroying the socket. Even if a
|
|
1956
|
+
// future regression creates two clients, the replaced one cannot keep
|
|
1957
|
+
// handling fleet_outbound messages as an orphan.
|
|
1958
|
+
existing.removeAllListeners();
|
|
1939
1959
|
try {
|
|
1940
|
-
existing.close();
|
|
1960
|
+
await existing.close();
|
|
1941
1961
|
}
|
|
1942
1962
|
catch (err) {
|
|
1943
1963
|
this.logger.debug({ err, name }, "IPC client close failed (likely already closed)");
|
|
1944
1964
|
}
|
|
1945
|
-
|
|
1946
|
-
|
|
1965
|
+
finally {
|
|
1966
|
+
if (this.instanceIpcClients.get(name) === existing) {
|
|
1967
|
+
this.instanceIpcClients.delete(name);
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1947
1970
|
}
|
|
1948
1971
|
const sockPath = join(this.getInstanceDir(name), "channel.sock");
|
|
1949
1972
|
if (!existsSync(sockPath))
|
|
@@ -2021,6 +2044,10 @@ export class FleetManager {
|
|
|
2021
2044
|
}
|
|
2022
2045
|
// Auto-reconnect on disconnect (unless intentionally stopping)
|
|
2023
2046
|
ipc.on("disconnect", () => {
|
|
2047
|
+
// A delayed event from a replaced/stale client must never delete the
|
|
2048
|
+
// current connection or start another reconnect loop.
|
|
2049
|
+
if (this.instanceIpcClients.get(name) !== ipc)
|
|
2050
|
+
return;
|
|
2024
2051
|
this.instanceIpcClients.delete(name);
|
|
2025
2052
|
if (this.ipcStoppingInstances.has(name))
|
|
2026
2053
|
return;
|
|
@@ -2032,7 +2059,20 @@ export class FleetManager {
|
|
|
2032
2059
|
}
|
|
2033
2060
|
}
|
|
2034
2061
|
/** Attempt IPC reconnection with exponential backoff */
|
|
2035
|
-
|
|
2062
|
+
ipcReconnect(name) {
|
|
2063
|
+
const inFlight = this.ipcReconnectInFlight.get(name);
|
|
2064
|
+
if (inFlight)
|
|
2065
|
+
return inFlight;
|
|
2066
|
+
const reconnect = this.runIpcReconnect(name)
|
|
2067
|
+
.finally(() => {
|
|
2068
|
+
if (this.ipcReconnectInFlight.get(name) === reconnect) {
|
|
2069
|
+
this.ipcReconnectInFlight.delete(name);
|
|
2070
|
+
}
|
|
2071
|
+
});
|
|
2072
|
+
this.ipcReconnectInFlight.set(name, reconnect);
|
|
2073
|
+
return reconnect;
|
|
2074
|
+
}
|
|
2075
|
+
async runIpcReconnect(name) {
|
|
2036
2076
|
for (let attempt = 1;; attempt++) {
|
|
2037
2077
|
if (this.ipcStoppingInstances.has(name) || !this.daemons.has(name))
|
|
2038
2078
|
return;
|