Orleans.StateMachineES
Production-ready state machines for Microsoft Orleans
Orleans.StateMachineES brings the power of state machines to your Orleans applications, wrapping the battle-tested Stateless library with Orleans-native async APIs, event sourcing, and advanced distributed patterns.
Why Orleans.StateMachineES?
Build reliable, maintainable distributed systems with:
- Compile-time Safety: 10 Roslyn analyzers catch state machine anti-patterns before they reach production
- Event Sourcing Built-in: Complete state history with replay capabilities - and it's 30% faster than regular state machines
- Production Resilience: Circuit breakers, retries, validation components, and distributed tracing out of the box
- Advanced Patterns: Hierarchical states, distributed sagas, orthogonal regions, and versioning
- High Performance: TriggerParameterCache provides ~100x speedup for parameterized triggers, optimized object pooling
Quick Start
Installation
dotnet add package Orleans.StateMachineES
dotnet add package Orleans.StateMachineES.Generators
Your First State Machine
using Orleans.StateMachineES;
public enum OrderState { Pending, Confirmed, Shipped, Delivered }
public enum OrderTrigger { Confirm, Ship, Deliver }
public interface IOrderGrain : IStateMachineGrain<OrderState, OrderTrigger>
{
}
public class OrderGrain : StateMachineGrain<OrderState, OrderTrigger>, IOrderGrain
{
protected override void BuildStateMachine()
{
StateMachine.Configure(OrderState.Pending)
.Permit(OrderTrigger.Confirm, OrderState.Confirmed)
.OnEntry(() => GrainFactory.GetGrain<INotificationGrain>(0)
.SendEmailAsync("Order received!"));
StateMachine.Configure(OrderState.Confirmed)
.Permit(OrderTrigger.Ship, OrderState.Shipped);
StateMachine.Configure(OrderState.Shipped)
.Permit(OrderTrigger.Deliver, OrderState.Delivered);
}
}
Usage
var order = grainFactory.GetGrain<IOrderGrain>(orderId);
// Fire transitions
await order.FireAsync(OrderTrigger.Confirm);
await order.FireAsync(OrderTrigger.Ship);
// Query state
var currentState = await order.GetStateAsync(); // OrderState.Shipped
var canDeliver = await order.CanFireAsync(OrderTrigger.Deliver); // true
var permitted = await order.GetPermittedTriggersAsync(); // [OrderTrigger.Deliver]
Learn more in the Getting Started guide →
Key Features
Core State Machines
The foundation of distributed state management with Orleans.
- StateMachineGrain Base Class: Orleans-native async state machine grain
- Parameterized Triggers: Pass up to 3 typed arguments with transitions
- Guard Conditions: Validate transitions with business logic
- State Inspection: Query current state, permitted triggers, and guard status
Event Sourcing
Complete state history and replay capabilities - 30.4% faster than regular state machines.
public class OrderGrain : EventSourcedStateMachineGrain<OrderState, OrderTrigger>
{
// Automatic event persistence and replay
// Use AutoConfirmEvents = true for maximum performance
}
- Automatic Event Persistence: All transitions saved as events
- State Replay: Rebuild grain state from event history
- Idempotency: Safe re-execution of transitions
- Stream Publishing: Orleans streams integration
Advanced Patterns
Hierarchical States: Parent-child state relationships with substates
StateMachine.Configure(OrderState.InTransit)
.SubstateOf(OrderState.Active)
.Permit(OrderTrigger.Delay, OrderState.Delayed);
Distributed Sagas: Multi-grain workflows with compensation
var saga = new OrderSaga();
await saga.ExecuteAsync(context);
// Automatic compensation on failure
Orthogonal Regions: Parallel independent state machines
var regions = new OrthogonalRegions<SmartHomeState, SmartHomeTrigger>();
regions.AddRegion("Lighting", lightingStateMachine);
regions.AddRegion("Climate", climateStateMachine);
Production Features
Circuit Breaker: Prevent cascading failures
var circuitBreaker = new CircuitBreakerComponent<State, Trigger>(new()
{
FailureThreshold = 5,
SuccessThreshold = 2,
OpenDuration = TimeSpan.FromSeconds(30)
});
Distributed Tracing: OpenTelemetry integration for observability
Health Checks: ASP.NET Core health monitoring
Versioning: Manage state machine evolution across deployments
Compile-time Safety
10 Roslyn analyzers catch issues before deployment:
| Analyzer | Description |
|---|---|
| OSMES001 | Prevents async lambdas in callbacks |
| OSMES002 | Blocks FireAsync in state callbacks |
| OSMES003 | Requires BuildStateMachine implementation |
| OSMES004 | Detects unreachable states |
| OSMES009 | Ensures initial state is set |
| ...and 5 more | See all analyzers → |
Visualization
Generate diagrams from your state machines:
var visualization = new StateMachineVisualization<State, Trigger>(stateMachine);
var mermaid = visualization.GenerateMermaidDiagram();
var dot = visualization.GenerateDotGraph();
var plantuml = visualization.GeneratePlantUmlDiagram();
var html = visualization.GenerateHtmlDiagram();
Performance
Optimized for production workloads:
- Event Sourcing: 5,923 transitions/sec (30% faster than regular grains)
- TriggerParameterCache: ~100x performance improvement for parameterized triggers
- ValueTask: Zero-allocation paths for synchronous operations
- FrozenCollections: 40%+ faster lookups in .NET 8+
- Object Pooling: Thread-safe, high-performance resource management
Complete Examples
Explore production-ready applications:
- E-Commerce Workflow: Event sourcing, timers, sagas
- Document Approval: Hierarchical states, multi-level approval
- Monitoring Dashboard: Health checks, metrics, observability
- Smart Home Automation: Orthogonal regions, source generator
Documentation
For Developers
- Getting Started - Installation and first state machine
- Core Concepts - Fundamental patterns
- Async Patterns - Critical async operation guidelines
- Cheat Sheet - Quick reference guide
For Architects
- Architecture Overview - Design decisions and patterns
- Performance Tuning - Optimization strategies
- Production Deployment - Production best practices
For Contributors
- Contributing Guide - How to contribute
- Analyzer Development - Writing analyzers
- Testing Strategy - Testing approach
API Reference
Browse the complete API documentation for all packages:
- Orleans.StateMachineES - Main library
- Orleans.StateMachineES.Abstractions - Core interfaces
- Orleans.StateMachineES.Generators - Analyzers and generators
Version Information
Current Version: 1.0.4 (Released November 2025)
Latest Improvements:
- Event sourcing performance: 30.4% faster with AutoConfirmEvents
- Enhanced production resilience components
- Comprehensive analyzer suite (10 analyzers)
- Performance optimizations across the board
View Changelog | Migration Guide
Community & Support
- GitHub: Orleans.StateMachineES Repository
- Issues: Report a bug
- Discussions: Ask questions
- NuGet: Package Downloads
License
Orleans.StateMachineES is licensed under the MIT License.
Ready to get started? Install Orleans.StateMachineES →