Stop promising a fatal counts wherever it is raised - #367
Merged
diolektor merged 1 commit intoSep 19, 2026
Merged
Conversation
Docs: - Two of the five places a worker-mode fatal can land recover the bailout without flagging the request, so it is finalized as a success and *clears* the consecutive-error count. The recycling table, the bullet above it and the released 0.11.0 entry all promised the opposite; they now name the three places that do count. - The paragraph under the table justified counting by the engine state a fatal leaves, then called a deadline in the same window neutral although it leaves the same state. It now gives the criterion the code applies: why the request ended, not what it left behind.
diolektor
deleted the
fix/worker-mode-docs-overstate-where-a-fatal-counts
branch
September 19, 2026 20:13
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.
Problem
The Recycling section of
docs/features/worker-mode.mdpresented the consecutive-error breaker as counting a request that comes apart "wherever it is raised, a shutdown function and a destructor run at the end of the request included". That holds for three places and fails for two. The arm that reports an uncaught exception and the arm that closes the output buffers and sends the headers both recover the bailout and set no outcome flag, so a request that fatals there is finalized down the success branch — which does not merely fail to count it, it clears the run other requests had built. Both windows execute ordinary userland code: a__toString()reached while the exception is reported, anob_start()callback, aheader_register_callback()callback. The overstatement therefore ran in the direction that costs a reader something: they plan for a breaker that sees every fatal, and two paths wipe the count instead.The paragraph under the outcomes table then justified counting by what a failure leaves behind — "a fatal there leaves the same wreckage the next request on that worker would inherit" — and in the next sentence made a
max_execution_timedeadline expiring in that same window neutral. A deadline is an ordinary fatal to the engine and is cleaned up by the same recovery, so it leaves the same state: the second sentence does not follow from the criterion the first one gives, and a reader who applies that criterion concludes the opposite of what the server does. The criterion the code actually applies is the cause — whether this worker is at fault — and only half of it had reached the documentation.The behaviour of the two unflagged arms is a separate defect and is not changed here. The released 0.11.0 changelog entry carried the same universal and is narrowed with it.
What changed
CHANGELOG.md, 0.11.0: "wherever it comes apart" removed, the enumeration after the colon kept.llms-full.txtregenerated.No behaviour changes — documentation only.
Verification
docs/,llms.txt,llms-full.txt,README.mdandCHANGELOG.mdreturns nothing. It returned four hits before the change.scripts/gen-llms-txt.sh --check— up to date, 58 pages.scripts/check-links.sh— 641 in-repo links, none broken.ext/oxphp_fiber.c: the three arms that raise the failure flag and are counted, the two that recover without one, the two shutdown-window arms that readPG(connection_status)for a deadline behind a "already came apart" guard, and the branch order in the scheduler's finalizer, which reads cancellation before failure.sapi_send_headers()runs the userland header callback throughsapi_run_header_callback(), which wraps it in nozend_try, so a fatal in it longjmps into the arm this text describes;php_output_end()pops the top handler throughphp_output_handler_op(), the userland output callback; andzend_timeout()ends inzend_error_noreturn(E_ERROR, …), taking the same error path as any other fatal, with only a bit onPG(connection_status)telling it apart. The interrupt helper checks the timeout flag before the interrupt function, so a deadline is recognized only by the two arms that read that bit — both of which carry the guard that keeps an established failure counted.