Repository navigation
fix(onlion): a stalled request body cannot hold an invocation; slow reports name their stage - #139
Merged
Merged
Conversation
…to the ceiling The 19:34-19:50 window split its twelve 120 s kills in two: seven at 601-667 MB (business logic, the embedding chain) and five at a constant 51.3359 MB - a number that never moved, which is what an invocation looks like when it is still waiting for its request body. readJson awaited reader.read() with no deadline of its own, so an upload that stopped halfway held the whole budget and was then killed with nothing to show. readJson now gives the body BODY_TIMEOUT_MS (30 s, NMG_BODY_TIMEOUT_MS to change) and answers 408 request_body_timeout, cancelling the stream. Also: the 60 s slow-request line reports `stage_isolate`, the measured stage the isolate is currently inside. Every 120 s kill so far needed a code read to say where it was; one string assignment per measured stage turns that into a field. On this platform (fresh isolate per request) the reading is exact; where an isolate is reused it is approximate, which the field name says. Both are additive; 37 PASS.
…n production The 2026-10-30 regression - callbacks.wasm deferred behind a factory, so `new WebAssembly.Instance(fn, ...)` threw and every SQLite-backed /search answered 503 in 75-150 ms - was invisible to `npm run verify`: Miniflare runs the wrangler build, which never executes the inline-wasm plugin. Only the endpoint found it. `test-edgeone-package.mjs` builds the EdgeOne function and asserts the artefact, not the source: - callbacks.wasm is inlined as an eager WebAssembly.Module (the loader imports it as one); - sqlite3.wasm is compiled on first use, so a request that never reads a partition does not decode or compile 1.5 MiB; - every inline base64 payload still compiles to a real module with exports; - the OPFS installers are gated off via globalThis.sqlite3ApiConfig - the only place the loader reads that setting; init()'s argument is silently ignored, which is exactly what the first attempt at that flag did; - the built entry still exports onRequest. Also tried and rejected: a Miniflare test for the stalled-body deadline. workerd buffers the request body before invoking the handler, so the stream never reaches readJson and the test hangs instead of exercising the deadline. The deadline is verified by reading the code path and by one live behaviour (408 within the window); a test that a no-op would pass is worse than no test, and one that hangs the suite is worse still. 38 PASS (verify now includes the packaging test).
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.
Doc owner:
docs/decisions/implemented/2026-10-30-body-deadline-and-stage.{md,zh-CN.md,terms.yaml}(added in this PR).Split of the 19:34-19:50 window (12 kills at 120 s):
readJsonawaitedreader.read()with no deadline: a stalled upload held the entire budget and died at the ceiling with nothing to show.Fixes:
BODY_TIMEOUT_MS(30 s,NMG_BODY_TIMEOUT_MS) → 408request_body_timeoutwith the stream cancelled; and the 60 s slow-request line now carriesstage_isolate(the measured stage the isolate is inside), so the next kill names its stage instead of needing a code read.Not verified
Not deployed. The 51 MB reading is consistent with the stalled-body mechanism but I have not seen a per-row log proving it for these exact five; the stage field is what will prove or disprove it next window. The Y group could also be an edge-side wait that never reaches the handler — in that case no
nmg_requestline appears and the fix is irrelevant rather than wrong.