-
Notifications
You must be signed in to change notification settings - Fork 127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add optional abort signal to fetch json and merge with timeout #2068
Merged
stephhuynh18
merged 3 commits into
develop
from
feature/net-1229-add-optional-abortsignal-to-fetchjson
Mar 8, 2022
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { timer, fromEvent, merge, Subscription } from 'rxjs' | ||
import { first } from 'rxjs/operators' | ||
|
||
export function mergeAbortSignals(signals: AbortSignal[]): AbortSignal { | ||
const controller = new AbortController() | ||
|
||
if (signals.length === 0) { | ||
throw Error('Need abort signals to create a merged abort signal') | ||
} | ||
|
||
if (signals.some((signal) => signal.aborted)) { | ||
controller.abort() | ||
return controller.signal | ||
} | ||
|
||
merge(...signals.map((signal) => fromEvent(signal, 'abort'))) | ||
.pipe(first()) | ||
.subscribe(() => { | ||
controller.abort() | ||
}) | ||
|
||
return controller.signal | ||
} | ||
export class TimedAbortSignal { | ||
private readonly _subscription: Subscription | ||
readonly signal: AbortSignal | ||
|
||
constructor(timeout: number) { | ||
const controller = new AbortController() | ||
this.signal = controller.signal | ||
|
||
if (timeout <= 0) { | ||
controller.abort() | ||
return | ||
} | ||
|
||
this._subscription = timer(timeout).subscribe(() => { | ||
controller.abort() | ||
}) | ||
} | ||
|
||
clear() { | ||
this._subscription?.unsubscribe() | ||
} | ||
} |
This file contains 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
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm frustrated by this loss of context. Looking at the node docs, it seems like
AbortController.abort
should be able to take an option string argreason
which could be used to provide a context string that the AbortSignal will include when it's aborted, and which can be used to give more meaningful error messages when an operation is cancelled. Sounds great! But in my testing I'm not actually able to get it to work - I keep getting an errorExpected 0 arguments, but got 1
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: I played around with different versions node using nvm. Node 16.14.0 does indeed have the
reason
arg, but Node 16.13.1 doesn't seem to have it. So I guess this is a very recent addition.But even though I can select node 16.14.0 with NVM and see it working by running
node
manually, when I try to use it in Ceramic I still get a compilation errorExpected 0 arguments, but got 1
. Any ideas why that would be @ukstv? Does that mean my Ceramic build is still using Node 16.13.1 for some reason, even thoughnode --version
is showing 16.14.0?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stbrody 1.
Expected 0 arguments
- if it is in TS, then Node.js types do not include reason parameter in the declarations. On my end vanilla Node.js (both 16.13 and 16.14) in REPL allow me to specify the reason.2. I tend to believe, it does not matter if we pass a reason there to the AbortController. node-fetch does not respect
reason
anyway.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do something like node-fetch/node-fetch#1462 (comment) though @stephhuynh18
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And, yes, it is a recent addition: https://nodejs.org/en/blog/release/v16.14.0/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used to do something like node-fetch/node-fetch#1462 (comment) but with this change we won't be able to tell if the request aborted because of a timeout or because the user called abort themselves.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not good.
Current code in the PR is indeed the most appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like there's a bunch of open issues on various repos to get this more fully supported. Agreed it's not worth doing anything more on this now, but we should revisit in the future once there's better support for abort reasons throughout the node ecosystem