Go Reference Go Report Card License: MIT
FSM-Go is a lightweight, high-performance, stateless finite state machine implementation in Go, inspired by Alibaba's COLA state machine component.
- 🪶 Lightweight - Minimal, stateless design for high performance
- 🔒 Type-safe - Built with Go generics for compile-time type checking
- 🔄 Fluent API - Intuitive builder pattern for defining state machines
- 🔀 Versatile Transitions - Support for external, internal, and parallel transitions
- 🧪 Conditional Logic - Flexible conditions to control when transitions occur
- 🎬 Action Execution - Custom actions that execute during transitions
- 🔄 Thread-safe - Designed for concurrent use in multi-threaded environments
- 📊 Visualization - Built-in support for generating state machine diagrams
go get github.com/lingcoder/fsm-go
package main import ( "fmt" "log" "github.com/lingcoder/fsm-go" ) // Define states type OrderState string const ( OrderCreated OrderState = "CREATED" OrderPaid OrderState = "PAID" OrderShipped OrderState = "SHIPPED" OrderDelivered OrderState = "DELIVERED" OrderCancelled OrderState = "CANCELLED" ) // Define events type OrderEvent string const ( EventPay OrderEvent = "PAY" EventShip OrderEvent = "SHIP" EventDeliver OrderEvent = "DELIVER" EventCancel OrderEvent = "CANCEL" ) // Define payload type OrderPayload struct { OrderID string Amount float64 } func main() { // Create a builder builder := fsm.NewStateMachineBuilder[OrderState, OrderEvent, OrderPayload]() // Define the state machine builder.ExternalTransition(). From(OrderCreated). To(OrderPaid). On(EventPay). WhenFunc(func(payload OrderPayload) bool { // Check if amount is valid return payload.Amount > 0 }). PerformFunc(func(from, to OrderState, event OrderEvent, payload OrderPayload) error { fmt.Printf("Order %s transitioning from %s to %s on event %s\n", payload.OrderID, from, to, event) return nil }) builder.ExternalTransition(). From(OrderPaid). To(OrderShipped). On(EventShip). WhenFunc(func(payload OrderPayload) bool { return true }). PerformFunc(func(from, to OrderState, event OrderEvent, payload OrderPayload) error { fmt.Printf("Order %s is being shipped\n", payload.OrderID) return nil }) // Define multiple source transitions builder.ExternalTransitions(). FromAmong(OrderCreated, OrderPaid, OrderShipped). To(OrderCancelled). On(EventCancel). WhenFunc(func(payload OrderPayload) bool { return true }). PerformFunc(func(from, to OrderState, event OrderEvent, payload OrderPayload) error { fmt.Printf("Order %s cancelled from %s state\n", payload.OrderID, from) return nil }) // Build the state machine stateMachine, err := builder.Build("OrderStateMachine") if err != nil { log.Fatalf("Failed to build state machine: %v", err) } // Create payload payload := OrderPayload{ OrderID: "ORD-20250425-001", Amount: 100.0, } // Transition from CREATED to PAID newState, err := stateMachine.FireEvent(OrderCreated, EventPay, payload) if err != nil { log.Fatalf("Transition failed: %v", err) } fmt.Printf("New state: %v\n", newState) }
Concept | Description |
---|---|
State | Represents a specific state in your business process |
Event | Triggers state transitions |
Transition | Defines how states change in response to events |
Condition | Logic that determines if a transition should occur |
Action | Logic executed when a transition occurs |
StateMachine | The core component that manages states and transitions |
- External Transition: Transition between different states
- Internal Transition: Actions within the same state
- Parallel Transition: Transition to multiple states simultaneously
Check the examples
directory for more detailed examples:
examples/order
: Order processing workflowexamples/workflow
: Approval workflowexamples/game
: Game state management
FSM-Go is designed for high performance:
- Stateless design minimizes memory usage
- Efficient transition lookup
- Thread-safe for concurrent use
- Benchmarks included in the test suite
FSM-Go provides a unified way to visualize your state machine with different formats:
// Default format (PlantUML) plantUML := stateMachine.GenerateDiagram() fmt.Println(plantUML) // Generate specific format table := stateMachine.GenerateDiagram(fsm.MarkdownTable) // Markdown table format fmt.Println(table) flow := stateMachine.GenerateDiagram(fsm.MarkdownFlowchart) // Markdown flowchart format fmt.Println(flow) // Generate multiple formats separately diagrams := stateMachine.GenerateDiagram(fsm.PlantUML, fsm.MarkdownTable, fsm.MarkdownFlowchart, fsm.MarkdownStateDiagram) fmt.Println(diagrams)
MIT © LingCoder