Skip to content

Make /api/shutdown actually exit the server process - #107

Merged
MasonXon merged 1 commit into
mainfrom
fix-server-shutdown-exit
Aug 10, 2026
Merged

Make /api/shutdown actually exit the server process#107
MasonXon merged 1 commit into
mainfrom
fix-server-shutdown-exit

Conversation

@MasonXon

@MasonXon MasonXon commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Problem

restart (and stop-service) left a leftover csghub-lite serve process behind each time, so processes accumulated.

Root cause: handleShutdown only called s.http.Shutdown(), which closes the HTTP listeners. But the Run loop is blocked on <-ctx.Done() waiting for a signal that never comes via the HTTP path, so the process never exits. stopBackgroundService polls the health endpoint, sees it go unresponsive, assumes the stop succeeded, and starts a fresh server — while the old process keeps running.

Fix

Store the signal.NotifyContext cancel function on the Server and invoke it from handleShutdown after closing the listeners. This drives Run through the same exit path as SIGINT/SIGTERM (graceful engine + listener shutdown), so the process actually terminates.

  • http.Server.Shutdown is idempotent (called once here, once in the Run exit path) — safe.
  • shutdownRuntime (closeAllEngines + CloseAll) is idempotent — safe to run twice.
  • shutdownCancel is nil-guarded; only set in Run, which always runs before the route can be hit.

Note

This prevents new orphans from accumulating. Existing leftover processes from before this fix are not auto-cleaned; clear them once with pkill -f "csghub-lite serve".

Before:
image

After:
image

handleShutdown only closed the HTTP listeners, leaving the Run loop
blocked on <-ctx.Done() waiting for a signal. stopBackgroundService
saw the port go unresponsive, assumed the stop succeeded, and started
a fresh server — while the old process kept running. Each restart
therefore left a leftover csghub-lite serve process behind.

Store the signal context's cancel on the Server and invoke it from
handleShutdown so the process exits via the same path as SIGINT/SIGTERM.
@MasonXon
MasonXon requested a review from ganisback August 10, 2026 10:05
@MasonXon
MasonXon merged commit 8c5c3f8 into main Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants