Summary #
Cancel in-flight dry_run: true previews and queued-but-unstarted dry_run: false imports immediately on server shutdown (SIGTERM / SIGINT) while preserving live SSE streams for an already-running import during the graceful ShutdownTimeout drain window, and deterministically reap stuck subprocess groups with an SSE error event if ShutdownTimeout expires.
Changes #
- Two-phase shutdown contexts & subprocess drain (
internal/server/server.go,cmd/goosefoot/main.go):- Add
ShutdownTimeout(DefaultShutdownTimeout = 15s) toserver.Config. - Keep
r.Context()strictly scoped to client disconnects (do not wireListenAndServe'sctxintohttpServer.BaseContext), preventing an actively running import from prematurely detaching its SSE stream before deliveringevent: complete. - Trigger
shutdownContextimmediately on<-ctx.Done()beforehttpServer.Shutdown(graceContext). - If
ShutdownTimeoutexpires, triggerforcedShutdownContextand drainhttpServer.Shutdown(bounded bySSEWriteTimeout) socmdstream.Runfinishes deliveringSIGKILLto anySetpgidchild process group, reaping it viacmd.Wait(), and flushing the final SSEerrorevent beforeListenAndServereturns tomain().
- Add
- Preview, queue, import & hook cancellation (
internal/server/pipeline.go,internal/server/import.go):- Hook
shutdownContextintorunPreviewviacontext.AfterFunc, flushing SSEevent: error("step":"preview","error":"server shutting down") when aborted by server shutdown. - Abort unstarted queued imports in
acquireQueueonshutdownContext(including simultaneous-wakeup recheck and queue token release), flushing SSEevent: error("step":"queued","error":"server shutting down") without starting new filesystem or SQLite mutations during shutdown. - Normalize forced-shutdown interruption in
runImportPipelineandrunPostImportHooksso forced cancellation duringimportingor post-import hooks stops remaining hooks, suppressesevent: complete, and emits SSEevent: errornaming the interrupted step with"error":"server shutting down"(while keeping non-shutdown hook failures non-fatal).
- Hook
- Tests (
internal/server/server_test.go):- Behavioral
ListenAndServetests covering immediatedry_runpreview cancellation, queued import abortion alongside active import + hook completion (event: complete), forced-shutdownimportingcancellation, forced-shutdown hook process-group reaping + remaining-hook suppression, and grace-deadline expiry right before hooks start.
- Behavioral