You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
compilers/openapi: the load phase never checks the context, so a cancel waits for most of the compile #970
At c387e25c the compile path checks ctx.Err() in seven places:
once between compilers, in the registry (compilers.go);
twice in openapi.go;
twice in operation;
once in schema;
once in compile/settle.
None of them is in load, which parses, scans and resolves the document. Detect takes no context at all. The engine checks the context only before each pass, and pass.Validate cannot be interrupted.
The golden spec (the Cloudflare API schema, cloudflare/api-schemasopenapi.json at 911ad78) takes about 7 s to compile. Through engine.Run:
a context cancelled 100 ms in makes Run return context.Canceled 4.6 to 5.0 s later (3 runs, on a shared machine);
with a context cancelled before the call, Compile performs 53.2 M of a full compile's 59.6 M allocations (89.4%) before it returns. This count does not depend on machine load;
a cancel that lands during Validate is ignored, and Run returns the full document with a nil error.
No goroutine is left behind in any of these runs.
Direction
A proposal:
Check the context between load's phases (parse, each scan, resolve, each chain and reach walk), and inside their loops at the granularity the cost tests already count.
Give Detect a context, or have the engine check it after detection.
Decide whether a cancel during the last pass returns the document or the error, and write it down.
Done when a test cancels at the start of each load phase and asserts that Compile returns context.Canceled having done at most a stated fraction of a full compile's counted work, with no wall-clock assertion.
Priority: P2, rule 6 (indirect impact: internal cost on the golden spec). A pre-cancelled Compile of the golden spec → 53.2 M of 59.6 M allocations, read from runtime.MemStats.Mallocs around one call (spec @911ad78, morphic @c387e25c).
#1016 deletes some of the phases this issue names and adds two that read no context. At 83ab508 the reach check and the chain, loop and mapping reads are deleted (load/reach*.go, chains.go, loops.go, mappings.go, scan/chains.go). In their place:
bind.Bind (compilers/openapi/internal/bind/table.go) takes no context and is bounded only by its work budget.
typed.Builder.Build loops over the landings without checking the context, which it only passes on to the parser's decode and walk.
A cancel still waits for the load phase to finish.
Activity
OmarAlJarrah commentedon Oct 20, 2026
#1016 deletes some of the phases this issue names and adds two that read no context. At 83ab508 the reach check and the chain, loop and mapping reads are deleted (
load/reach*.go,chains.go,loops.go,mappings.go,scan/chains.go). In their place:bind.Bind(compilers/openapi/internal/bind/table.go) takes no context and is bounded only by its work budget.typed.Builder.Buildloops over the landings without checking the context, which it only passes on to the parser's decode and walk.A cancel still waits for the load phase to finish.