Found while auditing Stack #633 (#628–#633).
Problem
ProcessPlatformAdapter.startWorker() registers SIGTERM/SIGINT/SIGQUIT handlers before performStartWorker() has completed. A first signal enters gracefulExit() → stopWorker() and waits on startupPromise before it can drain, close SQL, or exit.
If DB connection, queue creation, flow compilation, or worker startup hangs, the first signal does not complete graceful shutdown. The only escape is a second signal, which immediately exits with code 1 and skips the intended drain/cleanup path.
Relevant code:
pkgs/edge-worker/src/platform/ProcessPlatformAdapter.ts: startWorker(), performStopWorker(), handleSignal()
Impact
A process worker receiving SIGTERM during startup can remain alive past the supervisor grace period, then be force-killed or require a second signal. This is a regression from the previous ordering, where signal handlers were installed after startup completed.
Suggested fix
Make startup cancellation-aware, or install a bootstrap signal handler that aborts startup and performs bounded cleanup without waiting indefinitely for startupPromise. Keep the normal graceful-drain path for already-running workers, and add a test where startup never resolves and the first signal still completes deterministically.
Found while auditing Stack #633 (#628–#633).
Problem
ProcessPlatformAdapter.startWorker()registers SIGTERM/SIGINT/SIGQUIT handlers beforeperformStartWorker()has completed. A first signal entersgracefulExit()→stopWorker()and waits onstartupPromisebefore it can drain, close SQL, or exit.If DB connection, queue creation, flow compilation, or worker startup hangs, the first signal does not complete graceful shutdown. The only escape is a second signal, which immediately exits with code 1 and skips the intended drain/cleanup path.
Relevant code:
pkgs/edge-worker/src/platform/ProcessPlatformAdapter.ts:startWorker(),performStopWorker(),handleSignal()Impact
A process worker receiving SIGTERM during startup can remain alive past the supervisor grace period, then be force-killed or require a second signal. This is a regression from the previous ordering, where signal handlers were installed after startup completed.
Suggested fix
Make startup cancellation-aware, or install a bootstrap signal handler that aborts startup and performs bounded cleanup without waiting indefinitely for
startupPromise. Keep the normal graceful-drain path for already-running workers, and add a test where startup never resolves and the first signal still completes deterministically.