Final bikeshedding call: Fixing Control.Exception.bracket

Yuras Shumovich shumovichy at gmail.com
Thu Nov 13 20:31:42 UTC 2014


TLDR: the proposal is still a bad idea :))))))


On Thu, 2014-11-13 at 18:20 +0000, John Lato wrote:
>  hClose is a good example because it's pervasive and currently incorrect.
> But it's not the only one, and furthermore a lot of broken code is likely
> in libraries.

hClose is pervasive, but it doesn't mean the bug in it affects a lot of
code. Probably 99.(9)% hClose uses are correct. (it may affect more code
then I think, but nobody even created a ticket yet!) Do you really think
it is common to close handle while using it from other thread?

But yes, there is a lot of broken code in libraries. But we should fix
bugs instead if hiding them.  

> 
> For the most part, Haskellers don't need to worry about async exceptions.
> using them properly is a rather rare skill currently, and I suspect people
> are basically happy with that.  But it's dangerous because people actually
> do need to write async-safe code in cleanup handlers to get the behavior
> that usually mean.   One reason I think changing bracket etc is a better
> solution is that it helps minimize the average programmer's exposure to
> async exceptions.  It becomes easier to write correct cleanup handlers, for
> everyone. And if someone really needs an interruptible handler that can be
> available by a specialized function. But bracket and catches aren't the
> place for that.

Haskellers don't *want* to worry about async exception, but then should.
Otherwise let remove exception from language (yes, including synchronous
-- average Haskeller doesn't worry about them too.)

The proposal makes it easer to continue ignoring async exceptions. That
is why I'm arguing here against it. (Possible breakage if existing code
worries me too, but much less)

It is common myth that bracket saves you from async exceptions, but that
is simply not true. And the proposal will not make it true. So newcomers
learn to ignore async exceptions and continue doing that forever.

Even worse, when newcomer finally find out (most likely itself!!!), that
the myth is wrong, he doesn't get help from the community -- no docs, no
tutorials, no blogs. Everything he can find is a set of myths.


I started learning haskell 8 years ago, and I'm paid for haskell code 3
years already. When do you think I discovered that bracket is not enough
to handle async exceptions? Half a year ago(!)

I'll post the link again:
http://haskell.1045720.n5.nabble.com/Control-Exception-bracket-is-broken-td5752251.html
Note that nobody answered the question about hClose. Nobody explained
how to use interruptible exceptions in cleanup. Very few people actually
even care to replay. Because everybody learned to ignore async
exceptions.

Did you read this: http://www.well-typed.com/blog/97/
?
I hope you did. Because it is probably the *only* deep discussion of
*some* of the related issues. Unfortunately it appears after too late
for me, so I spent a lot of days discovering everything myself.

I even wrote my own library for exception handling:
https://github.com/Yuras/io-region/
I'm still not sure it is good. It even can be buggy. But I considered a
lot of design decisions, including unintrruptibleMask, and found then
unsatisfactory.

I personally find it easer to write exception safe code with io-region,
but you should understand async exceptions anyway. There is no easy way
unfortunately.

> 
> > > > So sync exceptions in hClose mean the program is incorrect, and the
> only
> > > > recourse is to prevent the sync exceptions in the first place.
> > > Fortunately,
> > > > these FDs are likely guaranteed to be valid so sync exceptions are
> > > > virtually ruled out.
> > > >
> > > > This is a general pattern with cleanups: a cleanup already has the
> > > > allocated resource at hand, which almost always rules out sync
> > > exceptions.
> > > > Also, exceptions during an error-induced cleanup cause dangerous
> > > > error-silencing anyway since we cannot handle an exception within an
> > > > exception.
> > >
> > > So you have to inspect all the code, directly or indirectly used by
> > > cleanup action, to ensure it doesn't throw sync exception (just to find
> > > that it is not the case -- a lot of cleanup actions can throw sync
> > > exceptions in some, probably rare, cases.) Someone argued, that was
> > > exactly the issue the proposal was trying to solve.
> > >
> >
> > Sync exceptions have nothing to do with the proposal.  The proposal itself
> > certainly doesn't argue this.
> 
> Sorry, I was not clear enough. I'm referring to the next:
> 
> On Tue, 2014-11-11 at 12:17 -0800, Merijn Verstraaten wrote:
> > Both Eyal and me have had trouble with this where we had to entire
> > half of base and part of the runtime, to figure out whether our code
> > was async exception safe. Auditing half the ecosystem to be able to
> > write a safe cleanup handler is *NOT* a viable option.
> 
> By banning sync exceptions in cleanup action you require Merijn to audit
> half the ecosystem to figure out whether his code is *sync* exception
> safe. Which probably requires the same amount of work as inspecting code
> for *async* exception safety.
> 
>  What? Nobody wants to ban sync exceptions in cleanups.  They should
> continue to work the way they do now.  Why do you bring this up?

I'm referring to this:

> > > > > So sync exceptions in hClose mean the program is incorrect, and the
> > only
> > > > > recourse is to prevent the sync exceptions in the first place.

What can it means except banning sync exceptions?

Actually I seriously considered baning exceptions in cleanup action,
but found it unsatisfactory


Sorry for long email.

Thanks,
Yuras




More information about the Libraries mailing list