#711: AbortSignal.timeout()

Visit on Github.

Opened Jan 28, 2022

Braw mornin' TAG!

I'm requesting a TAG review of AbortSignal.timeout(milliseconds).

This introduces a new static method, AbortSignal.timeout(milliseconds), which returns a newly-created AbortSignal that, after milliseconds milliseconds, becomes automatically aborted. The AbortSignal's reason property will be a "TimeoutError" DOMException. The main motivating use case for this is helping web developers easily time out async operations, such as fetch().

Further details:

  • I have reviewed the TAG's Web Platform Design Principles
  • Relevant time constraints or deadlines: No deadline, but the spec PR has been approved and has support from multiple implementers, so I'd expect the first implementation and PR will both land soon.
  • The group where the work on this specification is currently being done: WHATWG
  • The group where standardization of this work is intended to be done (if current group is a community group or other incubation venue): N/A
  • Major unresolved issues with or opposition to this specification: None known
  • This work is being funded by: Google

We'd prefer the TAG provide feedback as (please delete all but the desired option):

💬 leave review feedback as a comment in this issue and @-notify [@domenic, @shaseley ]

Discussions

2022-02-07

Minutes

Left question about API shape.

2022-07-11

Minutes

Peter: related to 737.

Peter: primary feedback was that it's weird to create as signal. Why not an abort controller?

Rossen: are you talking about the abort controller itself?

Peter: it's a factory method on abort signal. we thought : construct a regular abort controller and pass in a timeout parameter. Times out after a given time.

Peter: I don't understand the motivation... but it looks like it's been implemented by Firefox and Safari.

Dan: resolution: satisfied with concerns?

Peter: you want the ability to time out on a fetch. If all you want is a timeout then you pass that into the fetch.. but if you want the ability to timeout and abort... then you have to go through girations...

Dan: worth leaving that feedback?

Peter: yeah - if you want a timeout and the ability to abort then I think they made it more complicated than it needs to be. [Could be a middle way.]

Rossen: agree to leave that feedback.

Peter: ok will leave it.

2022-08-29

Minutes

Peter: last week we talked about this - it sounds like they are taking on the suggestion but not clear - we're waiting for that.

2022-11-14

Minutes

Lea: pending external feedback, why is it on agenda?

Dan: because it's been pending for ages

Lea: will look for developments...

Dan: we'll ask

2022-11-28

Minutes

bumped to next week

2022-12-19

Minutes

Tess: if factory method has landed ind esign principles.. then we should let them knpw - but beyond that we should keep waiting...

Peter: they did open an issue about the constructor argument... as I recall we didn't have an issue with them as a factory method...

Lea: looking through thread we're asking why it's a factory method on that class...

Peter: they opened an issue in whatwg issue 1110 - some pushback from Domenic.

Peter: i have mixed feelings... the original task of adding a new factory method - i'm fine with that. We had some suggestions about making it developer friendly.. common use case would be to use it with another abort signal. We had pushback from Domenic ... So is there a design principle we can pull out of this? We should either accept and document what Domenic's principle is or have a counter argument.

Domenic's comment https://github.com/whatwg/dom/issues/1110#issuecomment-1242811392 in the WhatWG issue

Lea: he's making multiple claims... differnet parts of the web platforn.. also discussion on AbortController ... he needs to file design principles issues about these.

<blockquote> Hi @domenic,

We looked at this again today. On the linked WHATWG issue you've made the comment:

I think this proposal is a bad idea and would be poor API design. The constructor of an object should vend its fundamental capabilities. It should not provide a syntactic shortcut for saving an extra line of setup, by connecting the constructed object to a totally different part of the web platform. (In this case, the event loop and timer subsystem.)

Furthermore, AbortControllers created in this way are harder to reason about. They have a hidden, implicit caller of abort(), which you cannot see. You have to know that whoever created it, hid such a call from you in the constructor. You can no longer scan for all abort() calls to find all ways the controller might be aborted.

I don't think we have evidence that the use case in question (roughly, creating an AbortController that is controlled by both a timeout and other callers) is very popular. And if we did, I don't think we have evidence that being explicit, using setTimeout(), is a huge burden. (Note that AbortSignal.any() is not actually needed, you can do const controller = new AbortController(); setTimeout(() => controller.abort(), 5000); and then pass controller onward.)

I hope we keep the AbortController constructor simple and focused on its core capabilities. Any syntactic sugar should continue to be done at the AbortSignal level, like we've done with AbortSignal.timeout() and like we're proposing to do with AbortSignal.any(). Static factory methods there both avoid messing up the API construct of the controller's constructor, and can pull their own weight by saving more than a single extra line (since they abstract away the entire AbortController object).

There are several design principles implicitly assumed in this message, and we'd like to discuss them separately, because we may or may not agree, and in any case it's good to get the benefit of a documented discussion that is separate from this particular issue.

For example, things like:

  • "The constructor of an object should not provide a syntactic shortcut for saving an extra line of setup"
  • "It should not [connect] the constructed object to a totally different part of the web platform. (In this case, the event loop and timer subsystem.)"
  • That having a hidden implicit call to abort() is a bad idea — why?
</blockquote>

support from Peter, Tess, Dan

Lea: leaves comment

Dan: we can bring this back to the plenary too...