fix: auto-terminate stale bot instances to prevent port conflicts
- Added execSync import for child_process - Modified acquirePidfile() to send SIGTERM to old instances - Waits up to 2.5s for graceful shutdown with checks every 500ms - Prevents continuous restart loop when old PID holds port 3001 - Bot now self-heals on restart instead of crashing
This commit is contained in:
@@ -6,6 +6,7 @@ import { createServer } from 'http';
|
||||
import { WebSocketServer } from 'ws';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { execSync } from 'child_process';
|
||||
import { logger } from '../utils/logger.js';
|
||||
import { checkEnv } from '../utils/env.js';
|
||||
import { getRTK } from '../utils/rtk.js';
|
||||
@@ -37,16 +38,33 @@ function acquirePidfile() {
|
||||
if (fs.existsSync(PIDFILE)) {
|
||||
const oldPid = parseInt(fs.readFileSync(PIDFILE, 'utf8').trim());
|
||||
// Check if old process is still alive
|
||||
try { process.kill(oldPid, 0);
|
||||
// Same PID or different process - just log warning, don't kill
|
||||
try { process.kill(oldPid, 0);
|
||||
// Old process is still running - kill it to prevent port conflicts
|
||||
if (oldPid !== process.pid) {
|
||||
logger.warn(`⚠ Another zCode instance (PID ${oldPid}) is running — keeping this instance (PID ${process.pid})`);
|
||||
logger.warn(`⚠ Another zCode instance (PID ${oldPid}) detected — terminating to prevent port conflict`);
|
||||
try {
|
||||
process.kill(oldPid, 'SIGTERM');
|
||||
logger.info(` ✓ Sent SIGTERM to PID ${oldPid}`);
|
||||
// Give it time to shut down gracefully
|
||||
for (let i = 0; i < 5; i++) {
|
||||
try { process.kill(oldPid, 0); }
|
||||
catch { break; } // Process is dead
|
||||
if (i < 4) {
|
||||
// Sleep 500ms between checks
|
||||
execSync('sleep 0.5', { stdio: 'ignore' });
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logger.warn(` Failed to kill old PID ${oldPid}: ${e.message}`);
|
||||
}
|
||||
} else {
|
||||
logger.info(`✓ Pidfile already acquired by this instance (PID ${process.pid})`);
|
||||
}
|
||||
// Don't kill - just continue with current process
|
||||
return;
|
||||
} catch { /* old PID dead, safe to acquire */ }
|
||||
// Continue - old process should be dead now
|
||||
} catch {
|
||||
// Old PID dead, safe to acquire
|
||||
logger.info(` Old PID ${oldPid} is no longer running`);
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(PIDFILE, process.pid.toString());
|
||||
logger.info(`✓ Pidfile acquired: ${PIDFILE} (PID ${process.pid})`);
|
||||
|
||||
Reference in New Issue
Block a user