(pids, options)
| 537 | } |
| 538 | |
| 539 | function stopPids(pids, options) { |
| 540 | var targets = Array.from(new Set(pids || [])).map(function(pid) { |
| 541 | return parseInt(pid, 10); |
| 542 | }).filter(Number.isFinite); |
| 543 | for (var i = 0; i < targets.length; i++) { |
| 544 | console.log('[Lifecycle] Stopping PID ' + targets[i] + '...'); |
| 545 | try { process.kill(targets[i], 'SIGTERM'); } catch (e) {} |
| 546 | } |
| 547 | var attempts = 0; |
| 548 | while (targets.some(isPidRunning) && attempts < 10) { |
| 549 | sleepMs(500); |
| 550 | attempts++; |
| 551 | } |
| 552 | var remaining = targets.filter(isPidRunning); |
| 553 | for (var j = 0; j < remaining.length; j++) { |
| 554 | console.log('[Lifecycle] Force-killing PID ' + remaining[j]); |
| 555 | if (process.platform === 'win32') { |
| 556 | try { execFileSync('taskkill', ['/F', '/PID', String(remaining[j])], { stdio: 'ignore', windowsHide: true }); } catch (e) {} |
| 557 | } else { |
| 558 | try { process.kill(remaining[j], 'SIGKILL'); } catch (e) {} |
| 559 | } |
| 560 | } |
| 561 | if (options && options.unlinkPidFile) { |
| 562 | try { if (fs.existsSync(PID_FILE)) fs.unlinkSync(PID_FILE); } catch (_) {} |
| 563 | } |
| 564 | if (options && options.unlinkLock) { |
| 565 | var evolverLock = path.join(getRepoRoot(), 'evolver.pid'); |
| 566 | try { if (fs.existsSync(evolverLock)) fs.unlinkSync(evolverLock); } catch (_) {} |
| 567 | } |
| 568 | return { status: 'stopped', killed: targets }; |
| 569 | } |
| 570 | |
| 571 | // --- Lifecycle --- |
| 572 |
no test coverage detected