fix(client): remove abort listener on success in fetchWithTimeout#1893
Open
LeSingh1 wants to merge 1 commit into
Open
fix(client): remove abort listener on success in fetchWithTimeout#1893LeSingh1 wants to merge 1 commit into
LeSingh1 wants to merge 1 commit into
Conversation
When a caller passes a signal option, fetchWithTimeout adds an abort listener that forwards to its internal controller but never removes it on successful completion. The once: true option only self-removes when the signal actually fires. On Deno this matters because attaching a listener to a signal returned by AbortSignal.timeout() refs the underlying timer (Node keeps it unref'd regardless). The orphaned listener keeps that timer alive for the full timeout duration, so a process that finishes a request in 500ms can hang for the remainder of the caller's 30s timeout before exiting. Remove the listener in the finally block so the signal is no longer referenced once the request resolves. Fixes openai#1811
1 task
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 #1811.
fetchWithTimeoutattaches an abort listener to the caller'ssignalthat forwards to its internal controller. The listener is added with{ once: true }, so it self-removes when the signal actually fires, but it is never removed when the request completes successfully.On Node this is harmless because
AbortSignal.timeout()keeps its timer unref'd regardless of listeners. On Deno, attaching a listener to a signal returned byAbortSignal.timeout()refs the underlying timer. The orphaned listener keeps that timer alive for the full timeout duration, so a request that completes in 500ms blocks process exit for the remainder of a caller's 30s timeout.The fix removes the listener in the existing
finallyblock alongsideclearTimeout. Theabortreference is already hoisted into the enclosing scope, so no other changes are needed.Repro (from the linked issue)
Tests
Added a regression test in
tests/index.test.tsthat spies onaddEventListener/removeEventListenerof a caller-suppliedAbortSignaland asserts the same listener reference is both added and removed once the request resolves. Fulltests/index.test.tssuite (61 tests) passes against the mock server.