[Haskell-cafe] ANN: asynchronous-exceptions
jmacristovao at gmail.com
Wed Feb 5 22:13:19 UTC 2014
By mere chance today I was, about the same time you published your
library, working on the suggestion made by Michael in the end of his
original blog post: splitting the async exceptions part from
classy-prelude (he is ok with this).
I was not yet sure about the namespace, I had opted for:
But yours makes more sense,
I agree that the two solutions address different problems, and as you
say, for controlled situations where performance is critical yours
indeed adds less overhead. But for more general solutions, Michael's
solution - split from Classy prelude, seems to be the way to go, and
thus my 'split' makes sense if you don't need the remaining classy
As such, I was considering the namespace:
To differentiate from yours, signaling that it handles _all_ exceptions.
What do you think?
Anyhow, I also think Joachim suggestion (of at least implementing the
new exception classes in base-compat) makes sense, so I volunteer to
add to the work I already done here:
(If the patch gets accepted, of course).
2014-02-05 Roman Cheplyaka <roma at ro-che.info>:
> Ok, this clears things up. I misinterpreted your approach thinking that
> you're also solving the problem of distinguishing async vs sync
> exceptions, only based on how they were thrown instead of their type.
> I now see that it isn't the case -- you're catching *all* exceptions.
> (And run the timeout handler in a different thread.)
> So no wonder that asynchronous-exceptions (whose description says that
> it lets differentiate between sync and async exceptions, in a certain
> sense) doesn't help you -- you simply don't want any exceptions at all.
> My use case is simpler -- I write testing libraries. If a test throws an
> exception, we have to decide whether we want to report it as a test's
> failure or it's a bigger problem and we want to wrap up.
> I don't think there's a universally right way to make this decision. It
> depends on what exceptions exist and what threads they can be thrown to.
> E.g. if there existed something like UserInterrupt but which could be
> thrown to any active thread, not only the main thread, then the approach
> "run in a separate thread and log any exceptions from that thread"
> simply wouldn't work.
> For tasty, based on the async exceptions I'm aware of, I think your
> approach is overall better. It's almost as simple, doesn't require
> patching 3rd-party timeout libraries, and catches StackOverflow (which
> is desirable). So I'll switch to it instead.
> For smallcheck, the overhead of forkIO might be significant, because it
> has to be performed for every single property check, and those can be
> numerous and very quick. I put together a simple benchmark
> (http://lpaste.net/99532 if anyone is interested) which shows that
> overhead can be noticable (16% for async vs 4% for simple catch) but
> tolerable, and it will be even less for more realistic properties.
> So I'll probably use the async approach there, too, although I may
> reconsider that in the future if I ever get to optimizing smallcheck and
> squeezing out those percents.
> As for the package itself, let's see if others will find any good use
> cases for it. I'll update the docs with some conclusions from this
> And thanks for your input.
> * Michael Snoyman <michael at snoyman.com> [2014-02-05 18:48:22+0200]
>> I can't think of any situation in which the semantics you're implying make
>> sense. To me, catching synchronous exception is a simple concept: if an
>> exception is generated internally to `userAction`, then it's a synchronous
>> exception. If it was terminated by something external, then it's
>> asynchronous. I'm not sure what you're getting at about my approach
>> requiring knowledge of what's going on deep inside a library.
>> The real question which is not explained in your package is what use case
>> you're actually trying to address. Here's a prime example I've run into:
>> you're writing a web application which uses a third-party library. If that
>> library throws an exception of any type, you want to catch the exception
>> and display an appropriate error message (or perhaps return some data from
>> another source). However, we still want the web application to respect
>> timeout messages from the server to avoid slowloris attacks. The handler
>> code would look like:
>> myHandler = do
>> eres <- tryAnyDeep someLibraryFunction
>> case eres of
>> Left e -> tellUser "I'm sorry, there was an issue making the query"
>> Right x -> displayData x
>> The goal is that, under no circumstances, should someLibraryFunction be
>> able to case the exception to escape tryAnyDeep. This includes rethrowing
>> some async exception that it received from, e.g., a timeout. This would not
>> be honored by trySync.
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
More information about the Haskell-Cafe