[Haskell-cafe] ANN: asynchronous-exceptions

Michael Snoyman michael at snoyman.com
Thu Feb 6 09:07:37 UTC 2014


On Thu, Feb 6, 2014 at 8:17 AM, Roman Cheplyaka <roma at ro-che.info> wrote:

> > Am I getting this right?
>
> Not quite.
>
> The enclosed computation may get asynchronous exceptions whatever
> definition of 'asynchronous' you use -- the exact one (by throw method)
> or the approximate one (by type).
>
> Just a couple of examples:
>
> * The thread may catch an async exception from the RTS (such as
>   BlockedIndefinitelyOnMVar or StackOverflow)
> * The thread may spawn other threads, passing its pid to them, and one
>   of its children may eventually kill it
>
> So I'd say this method allows to catch any exceptions "related" to
> the computation, synchronous or asynchronous. It is this "relatedness"
> that is enforced by running it in a separate thread.
>
> Roman
>
>
I definitely think this is important to get our terminology right. A lot of
the scariness of async exceptions likely spawns from the fact that we use
the same term to refer to a number of very different cases. Let me give a
crack at breaking down exceptions:

* An exception with a synchronous type (e.g., IOException) thrown via
throwIO. This is the most synchronous of synchronous exceptions.
* An exception with an asynchronous type (e.g., UserInterrupt) thrown via
throwIO. There's legitimate room for debate as to what we should call this.
For my purposes, I'd want to call it a synchronous exception.
* An exception with a synchronous type thrown via throwTo. Similar to
previous bullet, but I'd consider this asynchronous.
* An exception with an asynchronous type thrown via throwTo. This is
solidly an asynchronous exception.

Then we have some more interesting questions:

* What *is* an asynchronous type? By including BlockedIndefinitelyOnMVar,
it seems like you're defining it to include any exception generated by the
RTS. However, I'd consider it a synchronous exception: it is generated in
direct consequence of performing an IO action. It just happens to be
generated by the RTS instead of via some library talking to the filesystem.
* What happens if an async exception is caught and then rethrown? Has it
transformed itself into a synchronous exception? That's a tricky question,
and likely depends on the exact manner in which is was caught.
* What happens if a function utilizes some form of asynchronous exception
mechanism to affect its behavior? The prime example of this is `timeout`,
or better, the `asyncTimeout` function I displayed above. Internally to
that function, I think that's an async exception. However, for a *caller*
of that function, the behavior is actually synchronous: there was no
notification from the outside world changing the behavior of this function,
it simply has the possibility to terminate by throwing a Timeout, the same
way a function may terminate by throwing an IOException.

That last bullet is crucial to the question of whether
classy-prelude's and João's
catching functions are asynchronous or not. But given how overloaded the
term is, I'd be in favor of coming up with a new term to represent what
these catch functions are intended to do.

Michael
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20140206/da01b766/attachment.html>


More information about the Haskell-Cafe mailing list