transient- composing programs with multithreading, events and distributed computing

Safe HaskellNone




Transient implements an event handling mechanism ("backtracking") which allows registration of one or more event handlers to be executed when an event occurs. This common underlying mechanism called is used to handle three different types of events:

  • User initiated actions to run undo and retry actions on failures
  • Finalization actions to run at the end of a task
  • Exception handlers to run when exceptions are raised

Backtracking works seamlessly across thread boundaries. The freedom to put the undo, exception handling and finalization code where we want it allows us to write modular and composable code.

Note that backtracking (undo, finalization or exception handling) does not roll back the user defined state in any way. It only executes the user-defined handlers. State changes are only caused via user defined actions. These actions also can change the state as it was when backtracking started.

This example prints the final state as "world".

import Transient.Base (keep, setState, getState)
import Transient.Backtrack (onUndo, undo)
import Control.Monad.IO.Class (liftIO)

main = keep $ do
    setState "hello"
    oldState <- getState

    liftIO (putStrLn "Register undo") `onUndo` (do
        curState <- getState
        liftIO $ putStrLn $ "Final state: "  ++ curState
        liftIO $ putStrLn $ "Old state: "    ++ oldState)

    setState "world" >> undo >> return ()

See this blog post for more details.


Multi-track Undo

onBack :: (Typeable b, Show b) => TransientIO a -> (b -> TransientIO a) -> TransientIO a Source #

Run the action in the first parameter and register the second parameter as the undo action. On undo (back) the second parameter is called with the undo track id as argument.

back :: (Typeable b, Show b) => b -> TransIO a Source #

Start the undo process for a given undo track identifier type. Performs all the undo actions registered for that type in reverse order. An undo action can use forward to stop the undo process and resume forward execution. If there are no more undo actions registered, execution stop

forward :: (Typeable b, Show b) => b -> TransIO () Source #

For a given undo track type, stop executing more backtracking actions and resume normal execution in the forward direction. Used inside an undo action.

backCut :: (Typeable b, Show b) => b -> TransientIO () Source #

Delete all the undo actions registered till now for the given track id.

Default Track Undo

onUndo :: TransientIO a -> TransientIO a -> TransientIO a Source #

onBack for the default track; equivalent to onBack ().

undo :: TransIO a Source #

back for the default undo track; equivalent to back ().

retry :: TransIO () Source #

forward for the default undo track; equivalent to forward ().

undoCut :: TransientIO () Source #

backCut for the default track; equivalent to backCut ().

Finalization Primitives

onFinish :: (Finish -> TransIO ()) -> TransIO () Source #

Clear all finish actions registered till now. initFinish= backCut (FinishReason Nothing)

Register an action that to be run when finish is called. onFinish can be used multiple times to register multiple actions. Actions are run in reverse order. Used in infix style.

onFinish' :: TransIO a -> (Finish -> TransIO a) -> TransIO a Source #

Run the action specified in the first parameter and register the second parameter as a finish action to be run when finish is called. Used in infix style.

noFinish :: TransIO () Source #

Abort finish. Stop executing more finish actions and resume normal execution. Used inside onFinish actions.

initFinish :: TransIO () Source #

Execute all the finalization actions registered up to the last initFinish, in reverse order and continue the execution. Either an exception or Nothing can be