mirror of
https://github.com/mudler/LocalAI.git
synced 2026-05-30 11:36:31 -04:00
Two separate issues made graceful backend shutdown look ungraceful in the logs, even though the processes were being terminated correctly (go-processmanager defaults to process-group SIGTERM + 15s grace + SIGKILL): 1. "failed to read PID" — startProcess registers a per-process graceful- termination handler that calls Stop(), but StopAllGRPC (registered earlier, via app.Shutdown) already stopped and released store-tracked backends first. The second Stop() then failed reading the removed pidfile. Guard the handler with IsAlive() so it skips already-stopped processes; it still covers backends StopAllGRPC doesn't track (worker- supervised ones). 2. "Backend process exited unexpectedly" exitCode=-1 — the exit watcher treated only exit codes 0/143 as clean. But a child killed by our own SIGTERM/SIGKILL is reported by Go as exitCode -1 (signal termination), not the shell's 128+signal convention, so every intentional stop logged a false crash warning. The exit code can't distinguish an intended stop from a signal-induced crash. Track intent directly instead: a stoppingProcs sync.Map (keyed by the *process.Process pointer) is marked wherever LocalAI calls Stop() on purpose, and the exit watcher uses it to pick the log level — Info "stopped" when intentional, Warn "exited unexpectedly" otherwise (still catching real crashes). The raw exit code is reported as a field but no longer interpreted. Assisted-by: Claude:claude-opus-4-8 [Claude Code] Signed-off-by: Richard Palethorpe <io@richiejp.com>