fix(web): exempt planned --max-requests recycles from the crash-loop guard#523
Open
mirchaemanuel wants to merge 1 commit into
Open
Conversation
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 the crash-loop-guard half of #516 (Caveat 2): the
--webmaster counts scheduled--max-requestsworker recycles as startup deaths, so sustained traffic with a small quota tripsMAX_FAST_DEATHSand shuts the whole server down.What
RECYCLE_EXIT_CODE(86) afterserve()returns — which only happens on a planned--max-requestsrecycle. Documented as distinct from 0 (clean exit), 1 (worker errors), and 2 (usage errors).is_planned_recycle()(WIFEXITED && WEXITSTATUS == RECYCLE_EXIT_CODE) and exempts planned recycles from the fast-death accounting. A recycle neither increments nor resets the streak: healthy recycle churn cannot trip the guard, but it also cannot mask a real crash loop interleaved with it. Respawn behavior is unchanged — every dead worker is replaced.Why the "neutral" semantics
Resetting the streak on recycle would let a crash-looping handler hide behind recycle churn; counting it (status quo) kills a healthy server. Skipping the accounting entirely for planned recycles preserves both properties.
Verification
examples/web-hello,--workers 1 --max-requests 5, 80 sequential requests with client retries at recycle boundaries):served=49, server dead— master printed10 workers died on startup … giving up(the --web: linear per-worker latency ramp is a per-request refcount leak (chained subscript reads on nested arrays); --max-requests recycles miscounted by the crash-loop guard #516 repro);served=80 failed=0 server_alive=yes, zerogiving up.--listen 8.8.8.8:…→ master gives up and exits within seconds, as before.SIGSEGV/SIGKILL/SIGTERM) are not —WIFEXITEDgates the code check so a raw signal status can never alias the recycle code.cargo test -p elephc-web: 8 passed.web_max_requests_survives_sustained_recycle_churnintests/web_tests.rs: 30 requests through a quota of 2 (~15 recycles >MAX_FAST_DEATHS), asserts the master is still alive.cargo test --test web_tests web_max_requests: 2 passed.cargo build --releaseclean under the zero-warnings gate.Notes