
Thomas Conway wrote:
On 3/8/07, Chris Kuklewicz
wrote: Ah. Yes, I've independently discovered an equivalent technique. I'm building external btree/hash table code, and need to handle the case where you go to use a node that hasn't been paged in. My solution was simply to throw an exception, catch it, do the IO, then rerun the transaction.
Which sounds *almost* equivalent. My onRetry is different in that it lets one create a sequence of actions that are contingent on retrying the whole transaction. If the transaction commits then these actions are not performed; the actions queued by onCommit will be performed instead. What happens in your throw/catch case if I have stm1 = do some_stm_code_that_throws_your_exception stm2 = return Foo and I run "atomically (stm1 `orElse` stm2)" ? Answer: The exception will prevent running stm2. So I think a mixture of the two would be interesting. Perhaps I will add a "forceRetry" command to the MonadAdvSTM code that uses such an exception to prevent any orElse code from running.
Um, is unsafeIOToSTM $ atomically trans going to run you into problems?
YES! My code does not use "unsafeIOToSTM $ atomically" nor does it use "unsafePerformIO $ atomically". Both of those will kill the runtime system and thus the whole program. That fatal error is why there is the "*IO" functions like "newTVarIO" were added. My code uses "unsafeIOToSTM $ (IO code using MVar)" which is safe. -- Chris