[Haskell-cafe] STM Finalizers

David Turner dct25-561bs at mythic-beasts.com
Fri Jul 31 13:06:57 UTC 2015


Hi Michael,

I wholeheartedly agreed that timeout n $ atomicallyWithIO ... is important,
but that would generally work even if the finalizer ran masked wouldn't it?
Most actions that block are interruptible.

Put another way, I'd be interested to see how you could make serialize safe
without this. Something like this:

serialize :: [Operation d] -> DatabaseHandle d -> IO ()
serialize ops (DatabaseHandle _ h) =
    withMVar h (\h -> forM_ ops $ B.hPut h . runPut . safePut)
  `onException`
    magicalFileRollback h

(ignoring the tedious implementation of magicalFileRollback) doesn't look
quite right as if you got an async exception in the tiny window between
onException exiting and serialize exiting then the STM transaction would
roll back but the file wouldn't. I'm not convinced I totally understand
async exceptions so if you (or anyone else) can point out why this works
I'd be very grateful.

Cheers,

David




On 31 July 2015 at 13:18, Michael Schröder <mc.schroeder at gmail.com> wrote:

> Hi David, I appreciate your interest in my thesis!
>
> A finalizer which has non-atomic real-world effects needs to be quite
>> careful about undoing those effects when exceptions are thrown. [...] If
>> some of those B.hPut calls succeed but then one fails (e.g. the disk is
>> full) then the transaction will be rolled back, but the on-disk state will
>> be left partially written.
>>
>
> Yes, you are absolutely right! The example application lacks some of the
> safeguards one would expect in a production-ready system. It was intended
> to be more of a demonstration of how easily one can in principle build a
> database-like system on top of STM using finalizers. It still requires some
> engineering effort to make it entirely safe and practical. I should have
> documented this better—or just gone the extra mile and actually made it
> safe!
>
>
>> Even if the finalizer did include exception handling to deal with this
>> situation, what happens with asynchronous exceptions? Does the finalizer
>> run with async exceptions masked?
>>
>
> The finalizer does not run with async exceptions masked and you're right
> that one needs to be careful about how to deal with side-effects & async
> exceptions & cleanup within the finalizer—just like with any kind of I/O,
> really. In the TX example code, serialize should probably use
> withMVarMasked instead of withMVar. But I don't think the finalizer
> should run with async exceptions masked by default. There are uses cases
> where you really do want the finalizer to be interruptible from another
> thread, e.g. if you want to be able to timeout the whole transaction (STM
> part + finalizer part, as in: timeout n $ atomicallyWithIO ...)
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20150731/3140056f/attachment.html>


More information about the Haskell-Cafe mailing list