-
Notifications
You must be signed in to change notification settings - Fork 295
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
Userland AbortSignal #1195
Comments
Thanks for opening, Using I'm trying to get around having another way to dispatch things, @smaug---- can you elaborate what specifically about not being able to prevent other listeners from running bothers you? |
It would be odd to have special event dispatch mechanism just for AbortSignal. We've had the consistent way for decades - stop*Propagation works everywhere. Why it should behave differently here? Also, I'm having trouble to see the issue with using AbortSignal.any. Btw, is there a concrete issue here, or is this just some theoretical one? |
There is a real issue, userland uses At the moment AbortSignal already has a second dispatch mechanism but it's only exposed to the dom internally and |
Any update on this? I feel like we're adding a third way to do something (with any) - and the first two are problematic and there is no safe userland way to use AbortSignal until this is resolved (though to be fair in practice we haven't received complaints). |
Well, I'll keep this open to see if many other people are running into this and if we need to make further improvements. |
So we should be recommending people always do |
Maybe? That's certainly the only way to do it if you run into this problem. As I said above, if enough people run into this problem we should consider solving it better. |
@annevk should we maybe add a note in the specification suggesting it as a safe way to ensure a listener runs? |
I would prefer if I could depend on abort signals being delivered. It seems odd if the signal offers it, I say I want it, and some other unrelated code shoots the messenger and prevents it from ever arriving. This makes sense in a DOM tree where one node can say "OK I've handled this, it's done, no one else needs to handle it again". But responses to an abort are independent. Stopping an abort is like saying "OK I've stopped my piece, no one else needs to stop anything else, go ahead and leak all those resources". When would you ever need to legitimately cancel an abort partway through? The abort is the cancelation. You shouldn't be able to cancel cancelation. What about a new property on signal.addEventListener('abort', event => {
// Does nothing and raises a warning,
// just like preventDefault() when cancelable === false
event.stopImmediatePropagation()
})
const event = new Event('abort', { unstoppable: true })
signal.dispatchEvent(event) This is in line with existing functionality. It keeps the existing dispatch mechanism. It keeps the current default of events being stoppable, and adds an option to control it for events that need it. |
Here's an example of the effect. The user tries to stop everything but only one operation stops. https://bojavou.github.io/canceled-abort/ function aborted (event) {
// The rest of my app doesn't need this, stop the event for efficiency
event.stopImmediatePropagation()
reject(signal.reason)
} The developer thinks stopping the event is good for efficiency. That's reasonable and has been legitimate and beneficial since events began. But it's no longer true for an abort. Stopping an abort breaks user expectations. Once delivered, the abort signal cannot be triggered again, and there's no way to provide a new signal to the ongoing operations, so this breaks cancelation nonrecoverably. User intuition is cancelation should work when requested. Developer intuition is an abort signal should deliver what it offers. This is counterintuitive for everyone involved. Since there's no legitimate reason to stop an abort, and it has this highly visible and frustrating-to-the-user effect which the app can't recover from, I say it shouldn't even be possible. If |
We (node) shipped (are shipping) our own helper to add a listener without the stopImmediatePropagation issue as since Node is a server runtime a resource leak is potentially catastrophic for us. We'll hopefully also add a resource argument for it so it holds the listener weakly on the resource but that's planned for later.
I honestly wish I would have listened better to library authors when they were complaining about this before adding it to Node APIs but I think this is mostly blocked in the WHATWG side on someone doing the spec work to fix this API wise. |
Nice. I have special utils just for listening to abort signals, I'll at least be able to build it around this in Node. That's valuable. |
Splitting this from #1016.
Writing a robust userland
AbortSignal
consumer is tricky. In particular you might not get your event listener due to someone else listening callingstopImmediatePropagation()
.Possible solutions:
stopImmediatePropagation()
. (@smaug---- is not a fan of this as per the other thread.)AbortSignal.any()
to get a copy without other event listeners and registers their event listener there.cc @rniwa @smaug---- @mfreed7 @domenic @shaseley
The text was updated successfully, but these errors were encountered: