Skip to content
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

[Core] Make AbortController/AbortSignal work in the browser with fetch #6045

Closed
wants to merge 4 commits into from

Conversation

bterlson
Copy link
Member

@bterlson bterlson commented Nov 5, 2019

This is accomplished by vending browser-native AbortSignals rather than custom AbortSignals. I'm not entirely sure this is a good approach. While what I have works, the vended signals aren't instanceof AbortSignal. This could be surprising. E.g. AbortSignal.none instanceof AbortSignal is false. There may be other downsides I'm not thinking of yet.

That said, I experimented with a number of techniques to subclass the built-in AbortSignal, and none of them worked particularly well. The only alternative to this design I can think of uses a browser map to completely swap our AbortController and Signal with their native versions in the browser, but then linked signals wouldn't be supported.

@bterlson bterlson requested review from daviwil and chradek November 5, 2019 19:52
Copy link
Contributor

@chradek chradek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With regards to your comment on the instanceof AbortSignal check, this would pass if you compared an abortSignal to the global AbortSignal in browsers, correct? And the check should work in node.js since there is no global AbortSignal?

I think I did see that I could get our custom AbortSignal to pass the instanceof check in browsers (unfortunately this still failed when passed to fetch) if I set the AbortSignal prototype to a native AbortSignal's prototype. To do this I had to instantiate an AbortController, then access the signal's prototype. This felt 'hacky' but if we wanted the instanceof check to work badly enough is one thing we could try.

@@ -69,7 +69,13 @@ export class AbortController {
*/
constructor(...parentSignals: AbortSignalLike[]);
constructor(parentSignals?: any) {
this._signal = new AbortSignal();
if (typeof window !== "undefined" && typeof window.AbortController === "function") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we check self instead of window in case we're running inside a webworker?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're right... we need to abstract out these platform checks in a better way. We're checking window in a lot of places outside of this library.

@bterlson
Copy link
Member Author

bterlson commented Nov 6, 2019

With regards to your comment on the instanceof AbortSignal check, this would pass if you compared an abortSignal to the global AbortSignal in browsers, correct?

Yes. However, if you imported AbortSignal from our library and checked instanceof that, it would report false.

And the check should work in node.js since there is no global AbortSignal?

Also yes.

I think I did see that I could get our custom AbortSignal to pass the instanceof check in browsers (unfortunately this still failed when passed to fetch) if I set the AbortSignal prototype to a native AbortSignal's prototype. To do this I had to instantiate an AbortController, then access the signal's prototype. This felt 'hacky' but if we wanted the instanceof check to work badly enough is one thing we could try.

My opinion is that what's in this PR is a bit weird, but should be manageable. We can document that AbortSignal in the browser will vend native AbortSignal instances for compatibility reasons, and so instanceof may not work as you expect.

@ramya-rao-a ramya-rao-a requested review from xirzec and removed request for ramya-rao-a and ramya0820 December 16, 2019 22:40
@ramya-rao-a
Copy link
Contributor

Related to #5531

@ramya-rao-a
Copy link
Contributor

@daviwil, @xirzec, @chradek, @bterlson, What is our latest stance on this?

@xirzec
Copy link
Member

xirzec commented Jul 21, 2020

I'm on the fence. This feels messy, but maybe good enough to unblock browser scenarios?

@ghost ghost added the no-recent-activity There has been no recent activity on this issue. label Feb 25, 2022
@ghost
Copy link

ghost commented Feb 25, 2022

Hi @bterlson. Thank you for your interest in helping to improve the Azure SDK experience and for your contribution. We've noticed that there hasn't been recent engagement on this pull request. If this is still an active work stream, please let us know by pushing some changes or leaving a comment. Otherwise, we'll close this out in 7 days.

@ghost ghost closed this Mar 4, 2022
@ghost
Copy link

ghost commented Mar 4, 2022

Hi @bterlson. Thank you for your contribution. Since there hasn't been recent engagement, we're going to close this out. Feel free to respond with a comment containing "/reopen" if you'd like to continue working on these changes. Please be sure to use the command to reopen or remove the "no-recent-activity" label; otherwise, this is likely to be closed again with the next cleanup pass.

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Azure.Core no-recent-activity There has been no recent activity on this issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants