fix: release abandoned provider streams#88500
Conversation
|
Codex review: needs maintainer review before merge. Reviewed May 31, 2026, 12:11 PM ET / 16:11 UTC. Summary PR surface: Source +23, Tests +163, Other +1. Total +187 across 9 files. Reproducibility: yes. source-level: current main only releases managed provider responses on normal end, read error, or explicit cancel, and the linked report provides production lsof evidence of leaked sockets. I did not run a current-main multi-hour Gateway soak in this read-only review. Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Provider streams should cancel on parser exit and release guarded slots on abandoned wrappers without adding provider APIs, config, or fallback policy. Do we have a high-confidence way to reproduce the issue? Yes, source-level: current main only releases managed provider responses on normal end, read error, or explicit cancel, and the linked report provides production lsof evidence of leaked sockets. I did not run a current-main multi-hour Gateway soak in this read-only review. Is this the best way to solve the issue? Yes, with a maintainer-proof caveat: the shared guarded fetch wrapper is the right boundary for returning slots across provider transports. The remaining decision is whether the supplied local TCP/GC harness is enough or a longer live soak is required. AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against 63621eead219. Label changesLabel justifications:
Evidence reviewedPR surface: Source +23, Tests +163, Other +1. Total +187 across 9 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
f7c84df to
b9f986b
Compare
e5f281b to
bcea9c0
Compare
e645e90 to
766b36c
Compare
Signed-off-by: samzong <[email protected]>
766b36c to
a1db789
Compare
|
Land-ready after maintainer fixups. Summary:
Local verification:
CI:
|
Summary
Fixes #67461
Verification
git diff --check-> passed.node scripts/run-vitest.mjs src/agents/provider-transport-fetch.test.ts-> passed, 67 tests..agents/skills/autoreview/scripts/autoreview --mode local-> clean, no accepted/actionable findings.node --expose-gc --import tsx --input-type=modulewith a local HTTP streaming server,buildGuardedModelFetch, first-chunk read, abandonedResponse/reader, forced GC loop ->{"requestReceived":true,"firstChunkRead":true,"socketClosed":true,"writes":3}.Real behavior proof
Behavior addressed: abandoned provider streaming responses now release the guarded fetch slot and close the underlying streamed HTTP socket instead of waiting forever for a body that no caller is reading.
Real environment tested: local Node 24.14.0 process using the actual
buildGuardedModelFetchsource path, actualfetch/ReadableStream, and a real local TCP HTTP streaming server on127.0.0.1.Exact steps or command run after this patch: ran
node --expose-gc --import tsx --input-type=modulewith a local streaming HTTP server, calledbuildGuardedModelFetch(model, 5000, { sanitizeSse: false }), read the first response body chunk, dropped theResponseand body reader, then forced GC until the server observed socket close.Evidence after fix: Console output from the real local stream harness:
{"requestReceived":true,"firstChunkRead":true,"socketClosed":true,"writes":3}Observed result after fix: The copied live output shows the server received the model request, the client read the first streamed chunk, and the server observed the socket close after the abandoned managed response was garbage-collected.
What was not tested: live remote provider credentials, full Gateway agent run, and cross-OS/Testbox proof.
Performance accounting
No latency, throughput, or speedup claim. This moves abandoned-stream cleanup off a leak path; the runtime change adds one
FinalizationRegistryregistration per managed streamed response and unregisters it on normal release.AI-assisted
This PR was prepared with Codex.