a2acalling 0.6.47 → 0.6.48
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/bin/cli.js +55 -9
- package/package.json +1 -1
- package/src/server.js +12 -0
package/bin/cli.js
CHANGED
|
@@ -1954,6 +1954,19 @@ a2a add "${inviteUrl}" "${ownerText || 'friend'}" && a2a call "${ownerText || 'f
|
|
|
1954
1954
|
return;
|
|
1955
1955
|
}
|
|
1956
1956
|
|
|
1957
|
+
// Pre-start cleanup: kill any existing a2a server from a previous run
|
|
1958
|
+
try {
|
|
1959
|
+
const { killExistingServer } = require('../src/lib/pid-file');
|
|
1960
|
+
const cleanup = killExistingServer();
|
|
1961
|
+
if (cleanup.killed) {
|
|
1962
|
+
console.log(` Stopped previous server (PID ${cleanup.pid}).`);
|
|
1963
|
+
// Brief pause to let the port free up
|
|
1964
|
+
await new Promise(r => setTimeout(r, 500));
|
|
1965
|
+
}
|
|
1966
|
+
} catch (e) {
|
|
1967
|
+
// Best effort — continue with startup
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1957
1970
|
const isAlreadyListening = await isPortListening(serverPort, '127.0.0.1', { timeoutMs: 250 });
|
|
1958
1971
|
let serverPid = null;
|
|
1959
1972
|
if (!isAlreadyListening.listening) {
|
|
@@ -1987,7 +2000,15 @@ a2a add "${inviteUrl}" "${ownerText || 'friend'}" && a2a call "${ownerText || 'f
|
|
|
1987
2000
|
|
|
1988
2001
|
if (serverPid) {
|
|
1989
2002
|
console.log(' Server started.');
|
|
1990
|
-
config.
|
|
2003
|
+
const existingPids = (config.getOnboarding().server_pids || []).filter(p => {
|
|
2004
|
+
try { process.kill(p, 0); return true; } catch (e) { return false; }
|
|
2005
|
+
});
|
|
2006
|
+
if (!existingPids.includes(serverPid)) existingPids.push(serverPid);
|
|
2007
|
+
config.setOnboarding({
|
|
2008
|
+
server_pid: serverPid,
|
|
2009
|
+
server_pids: existingPids,
|
|
2010
|
+
server_port: serverPort
|
|
2011
|
+
});
|
|
1991
2012
|
} else {
|
|
1992
2013
|
console.log(' Using existing server.');
|
|
1993
2014
|
}
|
|
@@ -2318,24 +2339,43 @@ a2a add "${inviteUrl}" "${ownerText || 'friend'}" && a2a call "${ownerText || 'f
|
|
|
2318
2339
|
}
|
|
2319
2340
|
}
|
|
2320
2341
|
|
|
2321
|
-
// Kill server by PID from config (detached process started by quickstart)
|
|
2342
|
+
// Kill server by PID from config and PID file (detached process started by quickstart)
|
|
2322
2343
|
// Then verify the port is actually freed; if not, find and kill whatever holds it.
|
|
2323
2344
|
async function killServerPid() {
|
|
2324
|
-
let pid, serverPort;
|
|
2345
|
+
let pid, serverPort, serverPids = [];
|
|
2325
2346
|
try {
|
|
2326
2347
|
const { A2AConfig } = require('../src/lib/config');
|
|
2327
2348
|
const cfg = new A2AConfig();
|
|
2328
2349
|
const onboarding = cfg.getOnboarding();
|
|
2329
2350
|
pid = onboarding.server_pid;
|
|
2330
2351
|
serverPort = onboarding.server_port;
|
|
2352
|
+
serverPids = Array.isArray(onboarding.server_pids) ? onboarding.server_pids : [];
|
|
2331
2353
|
} catch (err) {
|
|
2332
|
-
// Config read failed — not fatal, continue
|
|
2333
|
-
return { ok: true, skipped: true };
|
|
2354
|
+
// Config read failed — not fatal, continue
|
|
2334
2355
|
}
|
|
2335
2356
|
|
|
2336
|
-
// Step
|
|
2337
|
-
|
|
2338
|
-
|
|
2357
|
+
// Step 0: Try PID file first (most reliable source)
|
|
2358
|
+
try {
|
|
2359
|
+
const { readPidFile, removePidFile } = require('../src/lib/pid-file');
|
|
2360
|
+
const filePid = readPidFile();
|
|
2361
|
+
if (filePid) {
|
|
2362
|
+
killPidSync(filePid);
|
|
2363
|
+
removePidFile();
|
|
2364
|
+
// If config PID is the same, don't double-kill
|
|
2365
|
+
if (filePid === pid) pid = null;
|
|
2366
|
+
}
|
|
2367
|
+
} catch (e) {
|
|
2368
|
+
// pid-file module load failed — continue with config PID
|
|
2369
|
+
}
|
|
2370
|
+
|
|
2371
|
+
// Step 1: Try to kill all tracked PIDs from config
|
|
2372
|
+
const allPids = new Set();
|
|
2373
|
+
if (pid) allPids.add(pid);
|
|
2374
|
+
for (const p of serverPids) {
|
|
2375
|
+
if (typeof p === 'number' && p > 0) allPids.add(p);
|
|
2376
|
+
}
|
|
2377
|
+
for (const p of allPids) {
|
|
2378
|
+
killPidSync(p);
|
|
2339
2379
|
}
|
|
2340
2380
|
|
|
2341
2381
|
// Step 2: Verify the port is freed
|
|
@@ -2359,7 +2399,13 @@ a2a add "${inviteUrl}" "${ownerText || 'friend'}" && a2a call "${ownerText || 'f
|
|
|
2359
2399
|
}
|
|
2360
2400
|
}
|
|
2361
2401
|
|
|
2362
|
-
|
|
2402
|
+
// Clean up PID file if it still exists
|
|
2403
|
+
try {
|
|
2404
|
+
const { removePidFile } = require('../src/lib/pid-file');
|
|
2405
|
+
removePidFile();
|
|
2406
|
+
} catch (e) {}
|
|
2407
|
+
|
|
2408
|
+
return { ok: true, pid, port: serverPort, skipped: !pid && allPids.size === 0 };
|
|
2363
2409
|
}
|
|
2364
2410
|
|
|
2365
2411
|
process.stdout.write('Stopping server... ');
|
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -22,6 +22,7 @@ const {
|
|
|
22
22
|
} = require('./lib/prompt-template');
|
|
23
23
|
const { findAvailablePort } = require('./lib/port-scanner');
|
|
24
24
|
const { createLogger } = require('./lib/logger');
|
|
25
|
+
const { writePidFile, removePidFile } = require('./lib/pid-file');
|
|
25
26
|
|
|
26
27
|
const DEFAULT_PORTS = [80, 3001, 8080, 8443, 9001];
|
|
27
28
|
const requestedPort = process.env.PORT ? parseInt(process.env.PORT, 10)
|
|
@@ -903,6 +904,7 @@ async function startServer() {
|
|
|
903
904
|
features: ['adaptive collaboration', 'auto-contacts', 'summaries', 'dashboard']
|
|
904
905
|
}
|
|
905
906
|
});
|
|
907
|
+
writePidFile(process.pid);
|
|
906
908
|
});
|
|
907
909
|
|
|
908
910
|
server.on('error', (err) => {
|
|
@@ -917,6 +919,16 @@ async function startServer() {
|
|
|
917
919
|
}
|
|
918
920
|
throw err;
|
|
919
921
|
});
|
|
922
|
+
|
|
923
|
+
// Graceful shutdown: clean up PID file
|
|
924
|
+
function shutdown() {
|
|
925
|
+
removePidFile();
|
|
926
|
+
server.close(() => process.exit(0));
|
|
927
|
+
// Force exit after 5s if connections won't close
|
|
928
|
+
setTimeout(() => process.exit(0), 5000).unref();
|
|
929
|
+
}
|
|
930
|
+
process.on('SIGTERM', shutdown);
|
|
931
|
+
process.on('SIGINT', shutdown);
|
|
920
932
|
}
|
|
921
933
|
|
|
922
934
|
startServer();
|