A Short, Simple, and Straightforward State (S4) Machine Library for .NET
This project is maintained by philiplaureano
S4M is a state machine library that I built to simplify building more resilient components in a distributed system. It was inspired by this article from Akka.NET that uses Actors with switchable behaviours to create components that can effectively manage themselves.
You can download the package here from NuGet.
public class SampleCircuitBreaker : StateMachine
{
// ...
}
private void Closed()
{
Receive<object>(msg =>
{
try
{
_commandHandler(msg);
_handledMessages.Add(msg);
}
catch (Exception e)
{
_exceptionsThrown.Add(e);
// Something happened - trip the circuit breaker
CurrentState = CircuitBreakerState.Open;
Become(Open);
}
});
}
private void Open()
{
Receive<object>(msg =>
{
try
{
_commandHandler(msg);
_handledMessages.Add(msg);
// If the call worked, let's close the circuit breaker again
CurrentState = CircuitBreakerState.Closed;
Become(Closed);
}
catch (Exception e)
{
// Ignore the error and keep the circuit breaker open since errors are still occurring
_exceptionsThrown.Add(e);
}
});
}
public SampleCircuitBreaker(/*...*/)
{
// ...
Become(Closed);
}
Stash.Stash()
method from within a Receive handler.Stash.UnstashAll()
method. Here is a complete example:
public class SampleUnstasher : StateMachine
{
private readonly ConcurrentBag<object> _messagesHandled = new();
private readonly ConcurrentBag<object> _messagesStashed = new();
public SampleUnstasher()
{
Become(StashEverything);
}
public void StartHandlingMessages()
{
Become(NotStashing);
}
private void StashEverything()
{
Receive<object>(msg =>
{
_messagesStashed.Add(msg);
// Stash every message that comes in
Stash.Stash();
});
}
private void NotStashing()
{
Receive<object>(msg =>
{
// Unstash every message that wasn't handled
Stash.UnstashAll();
// Handle every message that comes in
_messagesHandled.Add(msg);
});
}
public IEnumerable<object> MessagesStashed => _messagesStashed;
public IEnumerable<object> MessagesHandled => _messagesHandled;
}
TellAsync
method:
var myFSM = new SampleUnstasher();
var someRandomMessage = Guid.NewGuid();
await myFSM.TellAsync(someRandomMessage);
And that’s pretty much all you need to get started 😁
You can find the list of the latest changes here.
S4M is licensed under the MIT License. It comes with no free warranties expressed or implied, whatsoever.