mirror of
https://github.com/logos-messaging/logos-delivery.git
synced 2026-07-19 11:09:26 +00:00
Wait for graceful Anvil exit before escalating to KILL
stopAnvil gave Anvil a single 200ms window after TERM before sending KILL, risking a truncated state dump during regeneration. It also checked liveness with kill -0, which succeeds for an exited-but-unreaped zombie child, so the KILL escalation fired even after clean exits. Poll osproc running() (which reaps the child) for up to 10s instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
be9cf1b2ad
commit
6ff7b14a24
@ -633,10 +633,17 @@ proc stopAnvil*(runAnvil: Process) {.used.} =
|
||||
try:
|
||||
when not defined(windows):
|
||||
discard execCmdEx(fmt"kill -TERM {anvilPID}")
|
||||
# Give Anvil time to dump state on graceful shutdown before escalating to KILL.
|
||||
sleep(200)
|
||||
let checkResult = execCmdEx(fmt"kill -0 {anvilPID} 2>/dev/null")
|
||||
if checkResult.exitCode == 0:
|
||||
# Give Anvil time to dump state on graceful shutdown before escalating to
|
||||
# KILL; killing too early truncates the dump and corrupts the state file.
|
||||
# Poll via osproc `running` (which reaps the child) rather than `kill -0`,
|
||||
# since the latter also succeeds for an exited-but-unreaped zombie.
|
||||
const gracefulExitTimeoutMs = 10_000
|
||||
const pollIntervalMs = 100
|
||||
var elapsed = 0
|
||||
while runAnvil.running and elapsed < gracefulExitTimeoutMs:
|
||||
sleep(pollIntervalMs)
|
||||
elapsed += pollIntervalMs
|
||||
if runAnvil.running:
|
||||
warn "Anvil process still running after TERM signal, sending KILL",
|
||||
anvilPID = anvilPID
|
||||
discard execCmdEx(fmt"kill -9 {anvilPID}")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user