http: drain in-flight per-request coroutines on shutdown (#74)#77
Merged
EdmondDantes merged 1 commit intoJun 1, 2026
Conversation
Contributor
CoverageTotal lines: 81.35% → 81.26% (-0.09 pp)
|
Server shutdown disposed server_scope while per-request handler coroutines were still suspended, which aborts in debug builds (scope.c "Scope should be empty before disposal") and otherwise leaves the worker hanging on the parked coroutines. start() now drains server_scope on its lifecycle coroutine right after stop() wakes it (never inside stop(), which may be called from a handler living in server_scope), using the Scope's own orderly API: awaitCompletion() within the shutdown-timeout grace window, then cancel() + awaitAfterCancellation() for whatever is still parked. A guarded fallback runs in http_server_free for the freed-mid-flight path. server_scope is created with DISPOSE_SAFELY cleared so cancel() hard-terminates the handlers instead of zombifying them — a safe scope would zombify them and awaitAfterCancellation would wait forever. The grace window reuses the existing setShutdownTimeout knob (default 5s; 0 = cancel immediately). Adds tests/phpt/server/core/045-shutdown-drains-inflight.phpt.
45e6525 to
b9839d5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #74.
Server shutdown disposed
server_scopewhile per-request handler coroutines were still suspended, aborting in debug builds (scope.c"Scope should be empty before disposal") and otherwise hanging the worker on the parked coroutines.Fix
start()now drainsserver_scopeon its lifecycle coroutine right afterstop()wakes it (never insidestop(), which may be called from a handler living inserver_scope), using the Scope's own orderly API:awaitCompletion(Async\timeout(grace))— let in-flight handlers finish within thesetShutdownTimeoutgrace window (default 5s; 0 = cancel immediately).cancel()+awaitAfterCancellation()— hard-terminate whatever is still parked and wait for it to settle.A guarded fallback runs in
http_server_freefor the freed-mid-flight path (no-op in teardown/scheduler context).server_scopeis created withDISPOSE_SAFELYcleared socancel()hard-terminates handlers instead of zombifying them — a dispose-safely scope would zombify them andawaitAfterCancellationwould wait forever. Child request scopes inherit the non-safe mode.Tests
tests/phpt/server/core/045-shutdown-drains-inflight.phpt.request_context()repro: 60s hang → 0.08s clean shutdown.