Future cancellation

Jonas Sicking jonas at sicking.cc
Tue Apr 30 19:37:14 PDT 2013


I think the subclass is the way to go.

However there are some tricky issues that need to be resolved:

What happens if the Future is cancelled after it has been resolved? To
stick with the Future API, once you've started delivering results, you
shouldn't change what result is delivered.

What happens if cancel() is called multiple times?

Then there's of course the issue of what we should do with APIs that
combine several Futures into a single one. Like Future.every() etc.

Similarly, there's also the issue of what to do with chaining.

I'm tempted to say that if you create combined or dependent Futures,
you still only have the ability to cancel them through the original
CancelableFuture.

Like others have pointed out here, we need to keep "operations"
separate from "delivering results". Combined and dependent Futures are
combining the delivering of results, but they don't combine the
operations.

/ Jonas

On Tue, Apr 30, 2013 at 5:42 PM, Ron Buckton <rbuckton at chronicles.org> wrote:
> Jonas,
>
> As I mentioned to Alex Russel, I'm also interested in the benefits of using a subclass. I have two additional gists around cancellation, one that uses an external token for cancelation [1] (similar to .NET/C#), and another that uses a subclass [2] (though I still need to spend some additional time on the subclass sample).
>
> [1] https://gist.github.com/rbuckton/5490373
> [2] https://gist.github.com/rbuckton/5490482
>
> I agree with the sentiment that Future#cancel is a bad idea.
>
> Ron
>
>> -----Original Message-----
>> From: Jonas Sicking [mailto:jonas at sicking.cc]
>> Sent: Tuesday, April 30, 2013 4:47 PM
>> To: Ron Buckton
>> Cc: es-discuss; public-script-coord at w3.org; Tab Atkins Jr.
>> Subject: Re: Future cancellation
>>
>> On Mon, Apr 29, 2013 at 6:57 PM, Ron Buckton <rbuckton at chronicles.org>
>> wrote:
>> > I've created separate gists for three different ways that I am
>> > currently investigating as a means to support the cancellation of a
>> > Future. These can be found here:
>> >
>> >
>> >
>> > 1.       Cancellation using Future: https://gist.github.com/rbuckton/5486149
>> >
>> > 2.       Cancellation using Future.cancelable:
>> > https://gist.github.com/rbuckton/5484591
>> >
>> > 3.       Cancellation using Future#cancel:
>> > https://gist.github.com/rbuckton/5484478
>> >
>> >
>> >
>> > Each has a list of some of the benefits and issues I've seen while
>> > experimenting with each approach, as well as possible changes to the
>> > various APIs or algorithms for Future to make each happen.
>> >
>> >
>> >
>> > In general, cancellation of a Future can be beneficial in a number of cases.
>> > One example is the case where you are requesting a resource from a
>> > remote server using XHR. If the request was being made to fetch a page
>> > of data, and the user opted to move to the next page before the
>> > current page completed loading, it no longer becomes necessary to
>> > continue fetching the remote resource. In addition, it is no longer
>> > necessary to handle any additional computation or transformation logic
>> > that would have resulted from the successful completion of the fetch
>> > operation. Having the ability to cancel the request allows an
>> > application to quickly release resources that it no longer needs.
>> >
>> >
>> >
>> > It is also useful to be able to handle the cancelation of a long
>> > running task that might be executing in a Worker. In this case,
>> > cleanup logic that is part of cancelation would request the worker to
>> > close, ending the current operation and releasing resources.
>> >
>> >
>> >
>> > Both of the above examples are indicative of cancelling the root of an
>> > operation, but there are also circumstances where you might want to
>> > cancel a chained Future and any Future chained from it, without canceling
>> the root.
>> > In the previous example regarding paged data, I might wish to allow
>> > the fetch operation to complete so that I could cache the data for
>> > quick retrieval, but would only want to cancel any possible UI updates
>> > that might occur in a chained Future.
>> >
>> >
>> >
>> > I'm interested to hear what others think with respect to properly
>> > handling cancellation with Futures.
>>
>> I do not think that we should add cancellation on the base Future interface. I.e.
>> we shouldn't make *all* Futures cancellable.
>>
>> Cancelability should only be possible when the implementation of the Future
>> would actually stop doing work if the Future is cancelled. I.e.
>> cancelling a Future shouldn't simply prevent the result callbacks from being
>> called, but it should prevent whatever work is needed to calculate the result
>> from happening.
>>
>> However it would be very complex and expensive if we had to make all APIs
>> that want to use Futures also support being cancelled.
>>
>> The solution is to create a subclass of Future which allows the back-end work to
>> be cancelled. I.e. a CancelableFuture, or AbortableFuture. This subclass would
>> have a .cancel() or .abort() method on it. The FutureResolver created when the
>> CancelableFuture is created would have a callback which is called when
>> .cancel()/.abort() is called.
>>
>> This would be useful if we create an Future-based API for doing network
>> requests or file reading.
>>
>> In other words, the should be the choice of the implementor of a given API to
>> determine if it wants to return a Future which can be cancelled, or one that
>> can't. Obviously this needs to be documented for that API, just like you
>> document that the API returns a Future at all.
>>
>> / Jonas
>
>


More information about the es-discuss mailing list