<div dir="ltr">I think how you want to do this depends on the motivation of why you want to rollback.  Note that rolling back based on information *inside* the transaction means that the transaction must be consistent to successfully rollback.  If you want to trigger rolling back from *outside* the transaction you can do something like this:<div><br></div><div>atomicallyWithCancel :: TVar Bool -> STM x -> IO (Maybe x)</div><div>atomicallyWithCancel cancel act = atomically ((readTVar cancel >>= check . not >> return Nothing) `orElse` (Just <$> act))</div><div><br></div><div>Note that this still has to have a consistent view of memory to successfully "cancel", but if it reaches the end of the transaction it will notice an inconsistent read of the "cancel" tvar and restart the transaction.  Then it will quickly commit the cancel transaction that only reads a single TVar and returns Nothing.</div><div><br></div><div>Ryan</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Nov 28, 2020 at 4:07 PM amindfv--- via Haskell-Cafe <<a href="mailto:haskell-cafe@haskell.org">haskell-cafe@haskell.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I'd like to be able to give up on an STM transaction: roll back and don't retry.<br>
I've cooked up something with exceptions but it feels a bit icky to use exceptions for something like this - is there a better way?:<br>
<br>
    data Rollback = Rollback deriving (Show)<br>
    instance Exception Rollback<br>
<br>
    rollback :: STM x<br>
    rollback = throwSTM Rollback<br>
<br>
    atomicallyWithRollback :: STM x -> IO (Maybe x)<br>
    atomicallyWithRollback a =<br>
       (Just <$> atomically a)<br>
          `catch` (\Rollback -> pure Nothing)<br>
<br>
The alternative I've found is something like:<br>
<br>
    otherWay :: STM x -> IO (Maybe x)<br>
    otherWay a =<br>
       atomically $ (Just <$> a) `orElse` pure Nothing<br>
<br>
But this turns any "retry" in "a" into a rollback, and I'd like to have the option to do either (retry or rollback).<br>
<br>
Thanks,<br>
Tom<br>
<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div>