Skip to content

Fix HTTP server helper reporting success before shutdown finished - #3

Merged
umputun merged 1 commit into
masterfrom
fix/http-shutdown-completion
Aug 19, 2026
Merged

umputun merged 1 commit into
masterfrom
fix/http-shutdown-completion

Conversation

@paskal

@paskal paskal commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Previously, RunHTTPServerWithContext published the serve result as soon as startFn returned. http.Server.Shutdown makes Serve return ErrServerClosed at the beginning of the shutdown rather than at its end, so a caller receiving from the channel was told the server had exited while requests were still draining, and could terminate the process from under them. A shutdown error, a timeout included, only reached the log.

After this change a single coordinator owns the channel. On cancellation it awaits Shutdown, collects the serve result and only then publishes the outcome, joining the two errors when both are present.

What changes for existing callers:

  • Receiving from the channel is delayed by the graceful shutdown, up to the configured timeout, which is 10 seconds by default. Anything the handlers still need has to outlive that receive, so a dependency torn down on the old timing has to move after it.
  • A shutdown failure, context.DeadlineExceeded in particular, now arrives on the channel instead of only being logged, so a caller that treats a non-nil error as fatal will exit non-zero when the drain does not finish in time.

The signature, the options and the defaults are unchanged. Two deliberate limits are documented rather than papered over: a server that stops on its own is reported immediately and is not shut down, so a failed bind can still be retried on the same server, and a shutdown that times out publishes the timeout without waiting on startFn on top of the deadline it already missed, at the cost of not reporting a serving error that surfaces afterwards. Work net/http itself does not wait for, hijacked connections, connections dropped by Server.Close and RegisterOnShutdown callbacks, stays the caller's to track.

Three tests cover the new behaviour: the result stays unpublished while a handler drains, a shutdown that times out delivers context.DeadlineExceeded, and a server whose bind failed can be started again. Each fails against the previous implementation.

Previously, RunHTTPServerWithContext published the serve result as soon as
startFn returned, and http.Server.Shutdown makes Serve return ErrServerClosed
at the start of the shutdown rather than at its end. Callers were therefore
told the server had exited while requests were still draining, and any
shutdown error, including a timeout, only reached the log.

After this change a single coordinator owns the channel: on cancellation it
awaits Shutdown, collects the serve result and only then publishes the outcome,
joining the two errors when both are present. A server that stopped on its own
is reported immediately and is not shut down, so a failed start can be retried
on it; that also holds when the cancellation lands at the same moment. A
shutdown that times out publishes the timeout without waiting on startFn on top
of the deadline it already missed, at the cost of not reporting a serving error
that surfaces afterwards.

The signature and the defaults are unchanged.
@paskal
paskal requested a review from umputun as a code owner August 19, 2026 01:23
@umputun
umputun merged commit d2e5ff8 into master Aug 19, 2026
2 of 4 checks passed
@umputun
umputun deleted the fix/http-shutdown-completion branch August 19, 2026 01:39
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