Cancellation architectural observations

Kevin Smith zenparsing at
Mon Mar 2 23:18:35 UTC 2015

Hi Tab,

I'm afraid I don't quite understand.  How is one supposed to create a
cancelable task with async functions, under your proposed architecture?

On Mon, Mar 2, 2015 at 6:06 PM, Tab Atkins Jr. <jackalmage at> wrote:

> Thanks for this summary of some concerns!  All valid, I think.
> In the GitHub issue
> <>, there are
> some additional usability concerns, which I think make the
> cancellation token approach much less attractive, and lean the desired
> solution more towards a promise subclass.  In particular:
> Cancellations should "chain"
> ======================
> If you have a cancellable promise p1, and use .then() to produce a new
> promise p2, p2 should also be cancelable, and in the default case,
> should "chain up" to p1 and cause it to cancel as well.
> If you chain multiple promises off of p1, like p2a and p2b, then
> canceling either one of the p2X promises should do nothing, but
> cancelling *both* of them should cancel p1. In other words, p1 can
> ref-count its "child" promises that retain cancellation abilities, and
> cancel itself when everything consuming its result has been cancelled.
> This is important so you don't have to explicitly keep track of every
> single cancelable thing you're doing, if you're only using it to
> immediately chain onward again.  You can just care about the final
> result, and if you end up not needing it, you can cancel it and it
> walks back and tries to cancel everything your result depends on.
> Combinators should combine cancellations
> =================================
> If you do `let fp3 = FetchPromise.all(fp1, fp2)`, then an fp3.cancel()
> should try to cancel fp1 and fp2, as noted above.  You want all the
> (cancellation-aware) combinators to be just as friendly as chaining
> directly, for usability.
> You need to be able to "clean" a cancellable promise
> ========================================
> If the promise is what carries the cancellation ability, you need to
> be able to observe its value without carrying the cancellability
> around, to prevent spreading power around in an unwanted way (and
> prevent upping the "chained promises" refcount).  This is doable by
> just wrapping it in a standard promise - `Promise.resolve(fetch(...))`
> will return a normal non-cancellable promise.
> A cancellation token is basically an ocap, and that means you have to
> keep track of the ocaps explicitly and separately from the promise for
> the result.  This means more value-passing, and when you return
> another cancellable promise in the callback (like
> `fetch(...).then(x=>fetch(...))`), you have to explicitly smuggle that
> cancellation token out of the callback and hold onto both of them.
> Combinators become annoying, as you have to grab *all* of the cancel
> tokens used and hold them together, etc.
> Attaching cancellation to the promise just provides more usable
> behavior overall, without preventing safe behavior when you desire it.
> ~TJ
> _______________________________________________
> es-discuss mailing list
> es-discuss at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list