Click or drag to resize
StaMaPersistence of State Machines

Shows how to persist the current state of a state machine and how to resume from persistent storage

In case a process crashes or the process must be shut down for some other reason, it might sometimes be desired to resume the state machine execution at the state where it was before.

The StaMa StateMachine class provides the methods SaveState and Resume to save the state machine active state (and the history if present) to a Stream and to initialize the active state from a Stream.

The Resume may optionally execute entry actions or skip execution. It is up to the application to ensure that there is a consistent understanding regarding which conditions are given when the state machine has been resumed from a persisted state and resides within that state.

Saving and resuming

The following code shows how to use the SaveState and Resume methods:

SaveState and Resume
StateMachineTemplate t = new StateMachineTemplate();
t.Region("State1", false);
    t.State("State1");
        t.Transition("T1", "State2", "Event1");
    t.EndState();
    t.State("State2");
        t.Transition("T2", "State1", "Event2");
    t.EndState();
t.EndRegion();

// Create a state machine and start it
StateMachine stateMachine1 = t.CreateStateMachine();
stateMachine1.Startup();

// stateMachine1 is now ready for receiving events
stateMachine1.SendTriggerEvent("Event1");
// Check that stateMachine1 has executed transition "T1" to state "State2"
if (stateMachine1.ActiveStateConfiguration.ToString() != t.CreateStateConfiguration("State2").ToString())
{
    throw new Exception("stateMachine1 in unexpected state");
}

// Save the current state of stateMachine1
MemoryStream stream = new MemoryStream();
stateMachine1.SaveState(stream);
stream.Flush(); // Might write to persistent storage when using FileStream instead

// For demonstration purposes reset the MemoryStream to enable reading from it
// Real applications would open a FileStream
stream.Position = 0;

// Create a new state machine using the same structure and resume from saved state
StateMachine stateMachine2 = t.CreateStateMachine();
stateMachine2.Resume(stream, false);

// stateMachine2 is ready for receiving events
stateMachine2.SendTriggerEvent("Event2");
// Check that stateMachine2 has executed transition "T2" to state "State1"
if (stateMachine2.ActiveStateConfiguration.ToString() != t.CreateStateConfiguration("State1").ToString())
{
    throw new Exception("stateMachine2 in unexpected state");
}