Documentation
¶
Index ¶
- Variables
- func Dispatch(ctx context.Context, event Event) <-chan struct{}
- func DispatchAll(ctx context.Context, event Event) <-chan struct{}
- func DispatchTo(ctx context.Context, id string, event Event) <-chan struct{}
- func IsAncestor(current, target string) bool
- func LCA(a, b string) string
- func Match(state, pattern string) bool
- func Start[T Context](ctx context.Context, sm T, model *Model, config ...Config) T
- func Stop(ctx context.Context)
- type Config
- type Context
- type DecodedEvent
- type Element
- type Event
- type HSM
- type Model
- type RedefinableElement
- func Activity[T Context](fn func(ctx context.Context, hsm T, event Event), maybeName ...string) RedefinableElement
- func After[T Context](expr func(ctx context.Context, hsm T, event Event) time.Duration, ...) RedefinableElement
- func Choice[T interface{ ... }](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
- func Defer(events ...uint64) RedefinableElement
- func Effect[T Context](fn func(ctx context.Context, hsm T, event Event), maybeName ...string) RedefinableElement
- func Entry[T Context](fn func(ctx context.Context, hsm T, event Event), maybeName ...string) RedefinableElement
- func Exit[T Context](fn func(ctx context.Context, hsm T, event Event), maybeName ...string) RedefinableElement
- func Final(name string) RedefinableElement
- func Guard[T Context](fn func(ctx context.Context, hsm T, event Event) bool, maybeName ...string) RedefinableElement
- func Initial[T interface{ ... }](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
- func Source[T interface{ ... }](nameOrPartialElement T) RedefinableElement
- func State(name string, partialElements ...RedefinableElement) RedefinableElement
- func Target[T interface{ ... }](nameOrPartialElement T) RedefinableElement
- func Transition[T interface{ ... }](nameOrPartialElement T, partialElements ...RedefinableElement) RedefinableElement
- func Trigger[T interface{ ... }](events ...T) RedefinableElement
- type Trace
Constants ¶
This section is empty.
Variables ¶
var ( Kinds = kind.Kinds() ErrNilHSM = errors.New("hsm is nil") ErrInvalidState = errors.New("invalid state") ErrMissingHSM = errors.New("missing hsm in context") ErrInvalidPattern = errors.New("invalid pattern") )
var InitialEvent = Event{}
Functions ¶
func Dispatch ¶ added in v0.8.0
Dispatch sends an event to a specific state machine instance. Returns a channel that closes when the event has been fully processed.
Example:
sm := hsm.Start(...) done := sm.Dispatch(hsm.Event{Name: "start"}) <-done // Wait for event processing to complete
func DispatchAll ¶ added in v0.8.0
DispatchAll sends an event to all state machine instances in the current context. Returns a channel that closes when all instances have processed the event.
Example:
sm1 := hsm.Start(...) sm2 := hsm.Start(...) done := hsm.DispatchAll(context.Background(), hsm.Event{Name: "globalEvent"}) <-done // Wait for all instances to process the event
func DispatchTo ¶ added in v0.9.7
func IsAncestor ¶ added in v0.2.5
func LCA ¶ added in v0.2.5
LCA finds the Lowest Common Ancestor between two qualified state names in a hierarchical state machine. It takes two qualified names 'a' and 'b' as strings and returns their closest common ancestor.
For example: - LCA("/s/s1", "/s/s2") returns "/s" - LCA("/s/s1", "/s/s1/s11") returns "/s/s1" - LCA("/s/s1", "/s/s1") returns "/s/s1"
func Start ¶ added in v0.9.0
Start creates and starts a new state machine instance with the given model and configuration. The state machine will begin executing from its initial state.
Example:
model := hsm.Define(...) sm := hsm.Start(context.Background(), &MyHSM{}, &model, hsm.Config{ Trace: func(ctx context.Context, step string, data ...any) (context.Context, func(...any)) { log.Printf("Step: %s, Data: %v", step, data) return ctx, func(...any) {} }, Id: "my-hsm-1", })
Types ¶
type Config ¶ added in v0.9.0
type Config struct { // Trace is a function that receives state machine execution events for debugging or monitoring. Trace Trace // Id is a unique identifier for the state machine instance. Id string // TerminateTimeout is the timeout for the state activity to terminate. TerminateTimeout time.Duration // Name is the name of the state machine. Name string }
Config provides configuration options for state machine initialization.
type Context ¶
type Context interface { Element // State returns the current state's qualified name. State() string // Dispatch sends an event to the state machine and returns a channel that closes when processing completes. Dispatch(ctx context.Context, event Event) <-chan struct{} Stop(ctx context.Context) <-chan struct{} // contains filtered or unexported methods }
Context represents an active state machine instance that can process events and track state. It provides methods for event dispatch and state management.
func FromContext ¶ added in v0.5.0
FromContext retrieves a state machine instance from a context. Returns the instance and a boolean indicating whether it was found.
Example:
if sm, ok := hsm.FromContext(ctx); ok { log.Printf("Current state: %s", sm.State()) }
type DecodedEvent ¶ added in v0.9.99
func DecodeEvent ¶ added in v0.9.99
func DecodeEvent[T any](event Event) (DecodedEvent[T], bool)
type Element ¶ added in v0.3.0
type Element = elements.NamedElement
Element represents a named element in the state machine hierarchy. It provides basic identification and naming capabilities.
type Event ¶
Event represents a trigger that can cause state transitions in the state machine. Events can carry data and have completion tracking through the Done channel.
type HSM ¶
type HSM struct {
Context
}
HSM is the base type that should be embedded in custom state machine types. It provides the core state machine functionality.
Example:
type MyHSM struct { hsm.HSM counter int }
type Model ¶
type Model struct {
// contains filtered or unexported fields
}
Model represents the complete state machine model definition. It contains the root state and maintains a namespace of all elements.
func Define ¶ added in v0.2.2
func Define[T interface{ RedefinableElement | string }](nameOrRedefinableElement T, redefinableElements ...RedefinableElement) Model
Define creates a new state machine model with the given name and elements. The first argument can be either a string name or a RedefinableElement. Additional elements are added to the model in the order they are specified.
Example:
model := hsm.Define( "traffic_light", hsm.State("red"), hsm.State("yellow"), hsm.State("green"), hsm.Initial("red") )
func (*Model) Namespace ¶ added in v0.2.2
func (model *Model) Namespace() map[string]elements.NamedElement
func (*Model) Push ¶ added in v0.2.2
func (model *Model) Push(partial RedefinableElement)
type RedefinableElement ¶ added in v0.9.6
type RedefinableElement = func(model *Model, stack []elements.NamedElement) elements.NamedElement
RedefinableElement is a function type that modifies a Model by adding or updating elements. It's used to build the state machine structure in a declarative way.
func Activity ¶
func Activity[T Context](fn func(ctx context.Context, hsm T, event Event), maybeName ...string) RedefinableElement
Activity defines a long-running action that is executed while in a state. The activity is started after the entry action and stopped before the exit action.
Example:
hsm.Activity(func(ctx context.Context, hsm *MyHSM, event Event) { for { select { case <-ctx.Done(): return case <-time.After(time.Second): log.Println("Activity tick") } } })
func After ¶
func After[T Context](expr func(ctx context.Context, hsm T, event Event) time.Duration, maybeName ...string) RedefinableElement
After creates a time-based transition that occurs after a specified duration. The duration can be dynamically computed based on the state machine's context.
Example:
hsm.Transition( hsm.After(func(ctx context.Context, hsm *MyHSM, event Event) time.Duration { return time.Second * 30 }), hsm.Source("active"), hsm.Target("timeout") )
func Choice ¶
func Choice[T interface{ RedefinableElement | string }](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
Choice creates a pseudo-state that enables dynamic branching based on guard conditions. The first transition with a satisfied guard condition is taken.
Example:
hsm.Choice( hsm.Transition( hsm.Target("approved"), hsm.Guard(func(ctx context.Context, hsm *MyHSM, event Event) bool { return hsm.score > 700 }) ), hsm.Transition( hsm.Target("rejected") ) )
func Defer ¶
func Defer(events ...uint64) RedefinableElement
func Effect ¶
func Effect[T Context](fn func(ctx context.Context, hsm T, event Event), maybeName ...string) RedefinableElement
Effect defines an action to be executed during a transition. The effect function is called after exiting the source state and before entering the target state.
Example:
hsm.Effect(func(ctx context.Context, hsm *MyHSM, event Event) { log.Printf("Transitioning with event: %s", event.Name) })
func Entry ¶
func Entry[T Context](fn func(ctx context.Context, hsm T, event Event), maybeName ...string) RedefinableElement
Entry defines an action to be executed when entering a state. The entry action is executed before any internal activities are started.
Example:
hsm.Entry(func(ctx context.Context, hsm *MyHSM, event Event) { log.Printf("Entering state with event: %s", event.Name) })
func Exit ¶
func Exit[T Context](fn func(ctx context.Context, hsm T, event Event), maybeName ...string) RedefinableElement
Exit defines an action to be executed when exiting a state. The exit action is executed after any internal activities are stopped.
Example:
hsm.Exit(func(ctx context.Context, hsm *MyHSM, event Event) { log.Printf("Exiting state with event: %s", event.Name) })
func Final ¶
func Final(name string) RedefinableElement
Final creates a final state that represents the completion of a composite state or the entire state machine. When a final state is entered, a completion event is generated.
Example:
hsm.State("process", hsm.State("working"), hsm.Final("done"), hsm.Transition( hsm.Source("working"), hsm.Target("done") ) )
func Guard ¶
func Guard[T Context](fn func(ctx context.Context, hsm T, event Event) bool, maybeName ...string) RedefinableElement
Guard defines a condition that must be true for a transition to be taken. If multiple transitions are possible, the first one with a satisfied guard is chosen.
Example:
hsm.Guard(func(ctx context.Context, hsm *MyHSM, event Event) bool { return hsm.counter > 10 })
func Initial ¶
func Initial[T interface{ string | RedefinableElement }](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
Initial defines the initial state for a composite state or the entire state machine. When a composite state is entered, its initial state is automatically entered.
Example:
hsm.State("operational", hsm.State("idle"), hsm.State("running"), hsm.Initial("idle") )
func Source ¶
func Source[T interface{ RedefinableElement | string }](nameOrPartialElement T) RedefinableElement
Source specifies the source state of a transition. It can be used within a Transition definition.
Example:
hsm.Transition( hsm.Source("idle"), hsm.Target("running") )
func State ¶
func State(name string, partialElements ...RedefinableElement) RedefinableElement
State creates a new state element with the given name and optional child elements. States can have entry/exit actions, activities, and transitions.
Example:
hsm.State("active", hsm.Entry(func(ctx context.Context, hsm *MyHSM, event Event) { log.Println("Entering active state") }), hsm.Activity(func(ctx context.Context, hsm *MyHSM, event Event) { // Long-running activity }), hsm.Exit(func(ctx context.Context, hsm *MyHSM, event Event) { log.Println("Exiting active state") }) )
func Target ¶
func Target[T interface{ RedefinableElement | string }](nameOrPartialElement T) RedefinableElement
Target specifies the target state of a transition. It can be used within a Transition definition.
Example:
hsm.Transition( hsm.Source("idle"), hsm.Target("running") )
func Transition ¶
func Transition[T interface{ RedefinableElement | string }](nameOrPartialElement T, partialElements ...RedefinableElement) RedefinableElement
Transition creates a new transition between states. Transitions can have triggers, guards, and effects.
Example:
hsm.Transition( hsm.Trigger("submit"), hsm.Source("draft"), hsm.Target("review"), hsm.Guard(func(ctx context.Context, hsm *MyHSM, event Event) bool { return hsm.IsValid() }), hsm.Effect(func(ctx context.Context, hsm *MyHSM, event Event) { log.Println("Transitioning from draft to review") }) )
func Trigger ¶
func Trigger[T interface{ string | *Event | Event }](events ...T) RedefinableElement
Trigger defines the events that can cause a transition. Multiple events can be specified for a single transition.
Example:
hsm.Transition( hsm.Trigger("start", "resume"), hsm.Source("idle"), hsm.Target("running") )