W3C home > Mailing lists > Public > public-script-coord@w3.org > April to June 2013

Re: Future cancellation

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Tue, 30 Apr 2013 23:04:09 -0700
Message-ID: <CAAWBYDD01yv+Xm-Aj3D2nWVBZk1t9Xxxx6turAn2N36dNjRTKw@mail.gmail.com>
To: Brendan Eich <brendan@mozilla.com>
Cc: Lucas Smith <lsmith@lucassmith.name>, es-discuss <es-discuss@mozilla.org>, "public-script-coord@w3.org" <public-script-coord@w3.org>
On Tue, Apr 30, 2013 at 7:26 AM, Brendan Eich <brendan@mozilla.com> wrote:
> Lucas Smith wrote
>> IMO, cancelation is not appropriate for promises/futures. (sticking with
>> the name "promises", sorry for the distraction).
>
> Agreed.

Glad to see everyone agreeing on something about promises for a
change.  Unfortunately, I think you're all wrong. ^_^

Every future is "cancellable" already.  If you hand out your resolver,
anyone with it can preempt you and (prematurely?) fulfill the promise,
before your intended code-path finishes.  There are only two small
differences between normal promises and ones that are explicitly
"cancellable":

1. Some promises are holding onto resources (locks, network
connections, cpu time) which will be disposed of when they're
finished.  If you want to allow someone else to pre-empt you, you need
to be able to release these resources when that happens, so you're not
spinning your wheels doing work only to make a useless
"resolver.accept(dead-value)" that just gets ignored because the
promise is already fulfilled.  So, the constructor for the promise
needs some way to register some teardown code, called when the promise
is fulfilled.

2. The default case for cancellable promises is that they want their
promise consumers to be able to cancel them, as opposed to normal
promises that usually want to maintain complete control over their
fulfillment.  So, you probably want to return something with resolving
powers by default, in addition to the promise itself.

I think this is more than acceptable for a subclass, and I think it's
quite simple to do:

1. the constructor should take a second callback, which is called with
no arguments when the promise is fulfilled by any mechanism, and which
is intended for teardown code. It has no effect on the promise's
state.

2. The return value of the constructor should be a {promise, resolver}
pair, rather than just the promise itself.  This maintains the
separation of capabilities, but lets the consumer kill the promise if
they don't need it anymore.

This design adds minimal new surface area, solves the necessary
problems, and lets consumers either accept or reject the promise when
they cancel it, so they can provide a "default" value to other
consumers transparently.

~TJ
Received on Wednesday, 1 May 2013 06:04:55 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 21:37:49 UTC