*F# cancellation* - on second thought implicit cancellation through
cancellation like in F# is impractical because of the eagerness of
promises. I don't think it's a valid alternative here. I've discussed this
with Reed Copsey (an F# expert) and he explained the philosophy behind it
to me - it doesn't sound practical for JavaScript promises at all.

*Splitting into abort and ignore semantics - *that sounds like a great
idea, I think that ignore semantics are far more common for the use cases I
run into by the way. I think it might be a good idea to fire this off in a
separate ES-Discuss thread.

*Throwing and implicit cancellation *- I agree with Katelyn, throwing and
ignore cancellation are exclusive. As Bradley said - `return` (as in
generator `.return`) is a better mental model. `finally` blocks are run but
not `catch` blocks. In bluebird 3, cancellation is done with ignore
semantics - and we don't `throw` on cancellation (link again for
comparison: http://bluebirdjs.com/docs/api/cancellation.html ).

*Implicit cancellation being opt in - *I agree too, the nice property is
that cancellation becomes an optimization library authors get to make but
no other code breaks. A library can add support for freeing requests
earlier and you don't have to change your code in order to get the
optimization.

*Socket Lifetime Example - *In bluebird we map that with disposers (ref:
http://bluebirdjs.com/docs/api/promise.using.html ), we have found that in
the last few years although the library gets millions of downloads very few
people actually use `using`. It is an interesting motivating example and I
think we should collect those for any future proposal.

*XHR Example *- I think that ignore semantics can model that. The XHR
saving important changes would simply not be cancellable under implicit
cancellation - trying to cancel it would result in a no-op.

Cheers


On Wed, Jan 13, 2016 at 12:13 AM, Katelyn Gadd <[email protected]> wrote:

> Implicit cancellation doesn't make sense if it involves a throw.
> Furthermore, implicit cancellation would never happen for your example
> - the 'await' clearly depends on the result of the operation, so it is
> in use and it would not make sense for it to be implicitly cancelled.
> For the record, every time I've successfully dealt with implicit
> cancellation, it's opt-in - the library author implementing the
> asynchronous logic decides whether or not it will respond to implicit
> cancellation.
>
> Explicit cancellation ('abort', to use the terminology split Bradley
> advocated above) would potentially introduce a throw there, but that
> should be unsurprising, just as a socket being closed due to an
> ethernet cable getting unplugged would cause a socket operation to
> throw "unexpectedly".
>
>
> There are some subtle distinctions here that APIs tend to get wrong,
> of course. An example that might be informative:
>
> If you look at sockets, various APIs tend to have differences in how
> you deal with lifetime & closing handles. In some cases there are
> subtly different forms operations - for example if you look at Socket
> in the .NET framework, it exposes *three different/overlapping forms
> of lifetime management*, through the Shutdown, Close and Dispose
> methods. If you compare this with Rust's sockets API, the only
> explicit operation it exposes is 'shutdown', and the other two are
> expressed by dropping the value.
>
> For the average .NET user, you can treat all three as equivalent. For
> casual use cases you can just Dispose all IDisposable resources
> (files, sockets, graphics resources...) at the end of a function and
> be ready to go. But behaviorally they are different, and semantically
> they are different. A socket Shutdown followed by a Dispose will flush
> the read/write buffers (which can take time) and allow you to cleanly
> tear everything down, while a standalone Dispose is an instantaneous
> destruction of the socket, potentially breaking a transmission in the
> middle. In practice, this distinction represents that the socket is
> actually a group of related resources - read/write buffers, a network
> connection, etc - that can't simply be treated as a single unit with
> consistent lifetime.
>
> Oh yeah, and there's also the detail that you can shut down the write
> end of a socket but not the read end. :-)
>
> If you map this over to the browser, you can trivially come up with
> equivalent examples. When I issue XHR requests, some of those requests
> are more important than others. For example, an XHR that is saving
> important changes to an email draft should not be aborted if the user
> clicks on a hyperlink to load a new email. However, an XHR that is
> downloading an inline image for an email *can* be safely aborted at a
> moment's notice. You can think of this as equivalent to
> Shutdown/Dispose - you would want to Shutdown the draft save
> operation, flushing everything out, before closing the socket, and
> that takes time. In comparison, the image load is implicitly cancelled
> as soon as the image content is no longer needed, and that can
> terminate the underlying request if appropriate.
>
>
> On 11 January 2016 at 19:59, Kevin Smith <[email protected]> wrote:
> >> I think F#'s cancellation approach is also worth mentioning in the
> >> discussion of alternatives as it has implicit but token-based
> automatically
> >> propagating cancellation.
> >
> >
> > If you have any good links to reference materials on F#'s cancellation
> > architecture, feel free to include them for future reference.  I was
> unable
> > to find anything that clearly explained how implicit cancellation tokens
> are
> > discovered by child tasks, for instance.
> >
> > I find implicit cancellation to be somewhat sketchy.  For async
> functions,
> > it would mean that any await expression could potentially throw a
> > CancelError:
> >
> >     async function f() {
> >       let a = await 1; // This could throw?  What?
> >     }
> >
> > And there are certainly going to be scenarios where you *don't* want to
> > cancel a subtask.  It seems to me that cancellation semantics are best
> left
> > to the async operation itself, rather than assuming "crash-and-burn".
> >
> >
> > _______________________________________________
> > es-discuss mailing list
> > [email protected]
> > https://mail.mozilla.org/listinfo/es-discuss
> >
>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to