Documentation
¶
Overview ¶
Package hsm provides a powerful hierarchical state machine (HSM) implementation for Go.
Overview ¶
It enables modeling complex state-driven systems with features like hierarchical states, entry/exit actions, guard conditions, and event-driven transitions. The implementation follows the Stateforward HSM DSL/runtime contract, ensuring consistency across platforms.
Features ¶
- **Hierarchical States**: Support for nested states and regions.
- **Event-Driven**: Asynchronous event processing with context propagation.
- **Guards & Actions**: Flexible functional definitions for transition guards and state actions.
- **Type Safe**: Generics-based implementation for state context.
Usage ¶
Define your state machine structure and behavior using the declarative builder pattern:
type MyHSM struct {
hsm.HSM
counter int
}
model := hsm.Define(
"example",
hsm.State("foo"),
hsm.State("bar"),
hsm.Transition(
hsm.On("moveToBar"),
hsm.Source("foo"),
hsm.Target("bar"),
),
hsm.Initial(hsm.Target("foo")),
)
// Start the state machine
sm := hsm.Started(context.Background(), &MyHSM{}, &model)
<-hsm.Dispatch(context.Background(), sm, hsm.Event{Name: "moveToBar"})
Index ¶
- Constants
- Variables
- func AfterDispatch(ctx context.Context, hsm Instance, event Event) <-chan struct{}
- func AfterEntry[T stringLike](ctx context.Context, hsm Instance, state T) <-chan struct{}
- func AfterExecuted[T stringLike](ctx context.Context, hsm Instance, state T) <-chan struct{}
- func AfterExit[T stringLike](ctx context.Context, hsm Instance, state T) <-chan struct{}
- func AfterProcess(ctx context.Context, hsm Instance, maybeEvent ...Event) <-chan struct{}
- func AttributeType[T any]() reflect.Type
- func Call[T stringLike](ctx context.Context, hsm Instance, name T, args ...any) (any, error)
- func Get[T stringLike](ctx context.Context, hsm Instance, name T) (any, bool)
- func ID(hsm Instance) string
- func IsAncestor(current, target string) bool
- func IsKind(k uint64, bases ...uint64) bool
- func LCA(a, b string) string
- func MakeKind(bases ...uint64) uint64
- func Match[V stringLike, P stringLike](value V, patterns ...P) bool
- func Name(hsm Instance) string
- func New[T Instance](sm T, model *FinalizedModel, maybeConfig ...Config) T
- func QualifiedName(hsm Instance) string
- func Start[T Instance](ctx context.Context, sm T, maybeData ...any) T
- func Started[T Instance](ctx context.Context, sm T, model *FinalizedModel, maybeConfig ...Config) T
- func TakeSnapshot[S any, T snapshotTarget[S]](ctx context.Context, hsm T) S
- type AttributeChange
- type CallData
- type Clock
- type Completion
- func Dispatch[T context.Context](ctx T, hsm Instance, event Event) Completion
- func DispatchAll(ctx context.Context, event Event) Completion
- func DispatchTo[T stringLike](ctx context.Context, event Event, maybeIds ...T) Completion
- func Restart(ctx context.Context, hsm Instance, maybeData ...any) Completion
- func Set[T stringLike](ctx context.Context, hsm Instance, name T, value any) Completion
- func Stop(ctx context.Context, hsm Instance) Completion
- type ComposableModel
- type Config
- type DefaultModelFinalizer
- type DefaultModelValidator
- type Element
- type Event
- type EventSnapshot
- type ExpressionFunc
- type FinalizedModel
- type Group
- type HSM
- type Instance
- type Model
- type ModelFinalizer
- type ModelFinalizerFunc
- type ModelValidator
- type ModelValidatorFunc
- type ObservationData
- type OperationFunc
- type Queue
- type RedefinableElement
- func Activity(operations ...any) RedefinableElement
- func After(expr any) RedefinableElement
- func At(expr any) RedefinableElement
- func Attribute[T stringLike](name T, args ...any) RedefinableElement
- func Choice[T redefinableOrString](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
- func DeepHistory[T redefinableOrString](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
- func Defer[T interface{ ... }](events ...T) RedefinableElement
- func Effect(operations ...any) RedefinableElement
- func Entry(operations ...any) RedefinableElement
- func EntryPoint[T stringLike](name T, partialElements ...RedefinableElement) RedefinableElement
- func Every(expr any) RedefinableElement
- func Exit(operations ...any) RedefinableElement
- func ExitPoint[T stringLike](name T, partialElements ...RedefinableElement) RedefinableElement
- func Final[T stringLike](name T) RedefinableElement
- func Finalizer(finalizer any) RedefinableElement
- func Guard(expression any) RedefinableElement
- func Initial(partialElements ...RedefinableElement) RedefinableElement
- func Observe[T Instance](observer func(context.Context, T, Event), targets ...any) RedefinableElement
- func On[T interface{ ... }](events ...T) RedefinableElement
- func OnCall[T stringLike](name T) RedefinableElement
- func OnSet[T stringLike](name T) RedefinableElement
- func Operation[T stringLike](name T, maybeFn ...any) RedefinableElement
- func ShallowHistory[T redefinableOrString](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
- func Source[T redefinableOrString](nameOrPartialElement T) RedefinableElement
- func State[T stringLike](name T, partialElements ...RedefinableElement) RedefinableElement
- func SubmachineState[T stringLike, M ComposableModel](name T, machine M, partialElements ...RedefinableElement) RedefinableElement
- func Target[T redefinableOrString](nameOrPartialElement T) RedefinableElement
- func Transition[T redefinableOrString](nameOrPartialElement T, partialElements ...RedefinableElement) RedefinableElement
- func TransitionType(kindValue uint64) RedefinableElement
- func Validator(validator any) RedefinableElement
- func When(expr any) RedefinableElement
- type Snapshot
- type TransitionSnapshot
Constants ¶
const Version = "v1.3.2"
Version is the current semantic version of the hsm package.
Variables ¶
var ( // NullKind represents the absence of a kind or an uninitialized kind value. NullKind = kind.Make() // ElementKind is the base kind for all HSM elements. Every structural // component in the state machine hierarchy derives from ElementKind. ElementKind = kind.Make() // NamespaceKind represents elements that can contain named children, // enabling hierarchical name resolution for states and state machines. NamespaceKind = kind.Make(ElementKind) // VertexKind is the base kind for nodes in the state graph that can be // sources or targets of transitions, including states and pseudostates. VertexKind = kind.Make(ElementKind) // ConstraintKind represents guard conditions that control transition firing. ConstraintKind = kind.Make(ElementKind) // BehaviorKind represents executable behaviors such as entry, exit, and // transition effects that run during state machine execution. BehaviorKind = kind.Make(ElementKind) // ConcurrentKind represents behaviors that support concurrent execution // of multiple orthogonal regions. ConcurrentKind = kind.Make(BehaviorKind) // StateMachineKind represents the top-level state machine container that // owns regions, states, and transitions. Inherits from both ConcurrentKind // (for orthogonal regions) and NamespaceKind (for named child lookup). StateMachineKind = kind.Make(ConcurrentKind, NamespaceKind) // StateKind represents a state vertex that can contain nested regions, // entry/exit behaviors, and internal transitions. Inherits from VertexKind // (as a graph node) and NamespaceKind (as a container for child elements). StateKind = kind.Make(VertexKind, NamespaceKind) // SubmachineStateKind represents a state that composes a reusable child // machine under the containing state boundary. SubmachineStateKind = kind.Make(StateKind) // RegionKind represents an orthogonal region within a composite state or // state machine, containing vertices and transitions. RegionKind = kind.Make(ElementKind) // TransitionKind is the base kind for all transitions between vertices, // representing edges in the state graph. TransitionKind = kind.Make(ElementKind) // InternalKind represents internal transitions that execute without // exiting or re-entering the containing state. InternalKind = kind.Make(TransitionKind) // ExternalKind represents external transitions that exit the source state // and enter the target state, triggering exit and entry behaviors. ExternalKind = kind.Make(TransitionKind) // LocalKind represents local transitions that do not exit the containing // composite state when transitioning between its substates. LocalKind = kind.Make(TransitionKind) // SelfKind represents self-transitions where the source and target are // the same state, triggering exit and re-entry of that state. SelfKind = kind.Make(TransitionKind) // EventKind is the base kind for all events that can trigger transitions // in the state machine. EventKind = kind.Make(ElementKind) // TimeEventKind represents events triggered after a specified duration, // used for timeout-based transitions. TimeEventKind = kind.Make(EventKind) // CompletionEventKind represents events automatically generated when a // state completes all its internal activities or reaches a final state. CompletionEventKind = kind.Make(EventKind) // ChangeEventKind represents events triggered when a boolean condition // becomes true, enabling data-driven transitions. ChangeEventKind = kind.Make(EventKind) // CallEventKind represents events triggered by method calls on the state // machine, enabling synchronous event dispatch. CallEventKind = kind.Make(EventKind) // AttributeKind represents a model-level data slot. AttributeKind = kind.Make(ElementKind) // OperationKind represents a model-level callable operation. OperationKind = kind.Make(ElementKind) // ErrorEventKind represents events generated when an error occurs during // state machine execution. Inherits from CompletionEventKind as errors // typically complete the current processing. ErrorEventKind = kind.Make(CompletionEventKind) // PseudostateKind is the base kind for transient vertices that perform // control flow logic without representing stable states. PseudostateKind = kind.Make(VertexKind) // InitialKind represents the initial pseudostate that indicates the // default starting state when entering a region. InitialKind = kind.Make(PseudostateKind) // FinalStateKind represents a final state indicating that the enclosing // region has completed its execution. FinalStateKind = kind.Make(StateKind) // ChoiceKind represents a choice pseudostate that evaluates guards to // select among multiple outgoing transitions dynamically. ChoiceKind = kind.Make(PseudostateKind) // ObservationKind represents a model observation hook. ObservationKind = kind.Make(ElementKind) // EntryPointKind represents a connection point used to enter a submachine // through a named transient vertex. EntryPointKind = kind.Make(PseudostateKind) // ExitPointKind represents a connection point used to leave a submachine // through a named transient vertex. ExitPointKind = kind.Make(PseudostateKind) // ShallowHistoryKind represents a shallow history pseudostate that // remembers the most recently active direct substate of its region. ShallowHistoryKind = kind.Make(PseudostateKind) // DeepHistoryKind represents a deep history pseudostate that remembers // the full active state configuration within its region recursively. DeepHistoryKind = kind.Make(PseudostateKind) // CustomKind represents user-defined element types for extending the // HSM framework with application-specific constructs. CustomKind = kind.Make(ElementKind) )
Kind constants define the HSM type hierarchy using bit-packed inheritance. Each Kind encodes its own ID and the IDs of its ancestor types, enabling efficient type checking via kind.Is(). The hierarchy follows UML state machine concepts where elements can inherit from multiple parent kinds.
var ( // ErrNilHSM is returned when an operation is attempted on a nil state machine. ErrNilHSM = errors.New("hsm is nil") // ErrInvalidState is returned when attempting to access or transition to an invalid state. ErrInvalidState = errors.New("invalid state") // ErrMissingHSM is returned when the HSM instance cannot be found in the context. ErrMissingHSM = errors.New("missing hsm in context") // ErrMissingOperation is returned when an operation callback is required but not provided. ErrMissingOperation = errors.New("missing operation") // ErrInvalidOperation is returned when an operation callback has an unsupported function signature. ErrInvalidOperation = errors.New("invalid operation") // ErrAlreadyStarted is returned when a state machine has already been started. ErrAlreadyStarted = errors.New("hsm already started") // ErrUnknownAttribute is returned when a runtime attribute name is not defined. ErrUnknownAttribute = errors.New("unknown attribute") // ErrInvalidAttributeType is returned when a runtime attribute value has the wrong type. ErrInvalidAttributeType = errors.New("invalid attribute type") )
Error variables for common HSM error conditions. These sentinel errors can be checked using errors.Is for specific error handling.
var ( // InitialEvent is the completion event dispatched when a state machine starts. // It triggers the initial transition from the initial pseudostate to the first active state. InitialEvent = Event{ Name: "hsm/initial", Kind: CompletionEventKind, } // ErrorEvent is dispatched when an error occurs during state machine execution, // such as panics in concurrent behaviors or timeout errors. Use On(ErrorEvent) to handle errors. ErrorEvent = Event{ Name: "hsm/error", Kind: ErrorEventKind, } // AnyEvent is a wildcard event that matches any event not explicitly handled. // Transitions using On(AnyEvent) are only taken when no specific event transition matches. AnyEvent = Event{ Name: "*", Kind: EventKind, } // FinalEvent is the completion event dispatched when a state reaches its final state. // It triggers exit behaviors and propagates completion to parent regions. FinalEvent = Event{ Name: "hsm/final", Kind: CompletionEventKind, } // ObservationEvent is emitted to observation hooks for observed behaviors and transitions. ObservationEvent = Event{ Name: "hsm/observation", Kind: EventKind, } // InfiniteDuration represents an unbounded duration for timeout operations. // Use this when a behavior should run indefinitely without timing out. InfiniteDuration = time.Duration(-1) )
Built-in event types and special duration constants used by the HSM runtime.
DefaultClock is used when Config.Clock does not override timer behavior.
Functions ¶
func AfterDispatch ¶
AfterDispatch returns a channel that closes when the specified event is dispatched. Unlike AfterProcess, this signals when the event is added to the queue, not when processing completes. Use this helper for tests and deterministic observation only; it is not part of the supported production synchronization path.
func AfterEntry ¶
AfterEntry returns a channel that closes when the specified state is entered. The state parameter should be the fully qualified state path (e.g., "/parent/child"). Use this helper for tests and deterministic observation only; it is not part of the supported production synchronization path.
func AfterExecuted ¶
AfterExecuted returns a channel that closes when the specified state's do-activity has completed execution. The state parameter should be the fully qualified state path. Use this helper for tests and deterministic observation only; it is not part of the supported production synchronization path.
func AfterExit ¶
AfterExit returns a channel that closes when the specified state is exited. The state parameter should be the fully qualified state path (e.g., "/parent/child"). Use this helper for tests and deterministic observation only; it is not part of the supported production synchronization path.
func AfterProcess ¶
AfterProcess returns a channel that closes when event processing completes. If an event is provided, the channel closes after that specific event is processed. If no event is provided, the channel closes after the next processing cycle completes. Use this helper for tests and deterministic observation only; production callers should wait on the completion channel returned by Dispatch, Set, Restart, Stop, DispatchAll, or DispatchTo.
func AttributeType ¶ added in v1.3.1
AttributeType returns a reflect.Type token for explicit Attribute declarations.
func Get ¶ added in v1.0.3
Get reads an attribute value from the given state machine or from context.
func ID ¶
ID returns the unique identifier of a state machine instance. The ID is assigned when the state machine is created and remains constant throughout its lifecycle.
func IsAncestor ¶
IsAncestor checks whether current is an ancestor of target in the state hierarchy. It returns true if current appears in the path from the root to target's parent. Returns false if current equals target, or if either path is "." (relative root). The root path "/" is considered an ancestor of all other paths.
func LCA ¶
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 MakeKind ¶ added in v1.3.0
MakeKind creates a new kind using the canonical HSM kind implementation.
func Match ¶
func Match[V stringLike, P stringLike](value V, patterns ...P) bool
Match provides a simple interface, handling basic cases directly and delegating complex matching to the match function.
func Name ¶
Name returns the simple name of a state machine instance (without path prefix). This extracts the base name from the qualified name, e.g., "child" from "/parent/child".
func New ¶
func New[T Instance](sm T, model *FinalizedModel, maybeConfig ...Config) T
func QualifiedName ¶
QualifiedName returns the fully qualified name of a state machine instance. For nested state machines, this includes the parent path (e.g., "/parent/child"). For top-level state machines, this is typically just the name with a leading slash.
func Started ¶
func Started[T Instance](ctx context.Context, sm T, model *FinalizedModel, maybeConfig ...Config) T
Started 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.Started(context.Background(), &MyHSM{}, &model, hsm.Config{
ID: "my-hsm-1",
ActivityTimeout: 5 * time.Second,
})
func TakeSnapshot ¶
TakeSnapshot captures the current state of a machine or group. For a state machine it returns Snapshot. For a Group it returns []Snapshot in group order.
Types ¶
type AttributeChange ¶ added in v1.0.3
AttributeChange is the payload for attribute change events.
type Clock ¶ added in v1.0.8
type Clock struct {
After func(time.Duration) <-chan time.Time
NewTimer func(time.Duration) *time.Timer
}
Clock provides injectable timer functions used by the state machine runtime. Nil fields fall back to DefaultClock.
type Completion ¶ added in v1.3.1
type Completion <-chan struct{}
Completion is a receive-only completion channel. It remains compatible with `<-hsm.Dispatch(...)` while allowing callers to inspect runtime failures after the channel closes.
func Dispatch ¶
func Dispatch[T context.Context](ctx T, hsm Instance, event Event) Completion
Dispatch sends an event to a specific state machine instance. It returns a completion channel that closes when the event has been fully processed. Waiting on that channel is the supported production synchronization path before asserting on post-transition state. Go's completion channel can be received directly; call Completion.Err after it closes to inspect direct runtime submission failures.
Example:
model := hsm.Define(...)
sm := hsm.Started(context.Background(), &MyHSM{}, &model)
done := hsm.Dispatch(context.Background(), sm, hsm.Event{Name: "start"})
<-done // Wait for event processing to complete
func DispatchAll ¶
func DispatchAll(ctx context.Context, event Event) Completion
DispatchAll sends an event to all state machine instances in the current context. It returns a completion channel that closes when all selected instances have processed the event. Waiting on that channel is the supported production synchronization path before asserting on post-transition state.
Example:
sm1 := hsm.Started(context.Background(), &MyHSM{}, &model)
sm2 := hsm.Started(sm1.Context(), &MyHSM{}, &model)
done := hsm.DispatchAll(sm2.Context(), hsm.Event{Name: "globalEvent"})
<-done // Wait for all instances to process the event
func DispatchTo ¶
func DispatchTo[T stringLike](ctx context.Context, event Event, maybeIds ...T) Completion
DispatchTo sends an event to the selected state machine instances in the current context. It returns a completion channel that closes when all matching instances have processed the event. Waiting on that channel is the supported production synchronization path before asserting on post-transition state.
func Restart ¶
func Restart(ctx context.Context, hsm Instance, maybeData ...any) Completion
Restart stops a state machine and restarts it from the initial state. Optional data can be passed to reinitialize the state machine's data field. It returns a completion channel that closes when the restart completes. Waiting on that channel is the supported production synchronization path before asserting on post-transition state.
func Set ¶ added in v1.0.3
func Set[T stringLike](ctx context.Context, hsm Instance, name T, value any) Completion
Set updates an attribute value and emits an OnSet change event. It returns a completion channel that closes after the resulting processing completes. Waiting on that channel is the supported production synchronization path before asserting on post-transition state.
func Stop ¶
func Stop(ctx context.Context, hsm Instance) Completion
Stop gracefully stops a state machine instance. It returns a completion channel that closes after shutdown processing finishes. Waiting on that channel is the supported production synchronization path before asserting on post-transition state. If no instance is available, Stop returns the shared closed completion channel.
Example:
sm := hsm.Started(context.Background(), &MyHSM{}, &model)
// ... use state machine ...
<-hsm.Stop(context.Background(), sm)
func (Completion) Err ¶ added in v1.3.1
func (completion Completion) Err() error
Err returns the runtime failure associated with this completion, if any.
func (Completion) Wait ¶ added in v1.3.1
func (completion Completion) Wait() error
Wait waits for completion and returns Err.
type ComposableModel ¶ added in v1.3.1
type ComposableModel interface {
Model | *Model | FinalizedModel | *FinalizedModel
}
ComposableModel is a model value that can provide a submachine body.
type Config ¶
type Config struct {
// ID is a unique identifier for the state machine instance.
ID string
// ActivityTimeout is the timeout for the state activity to terminate.
ActivityTimeout time.Duration
// Clock overrides the timer functions used by the state machine runtime.
Clock Clock
// Queue overrides the event buffer used by the state machine runtime.
Queue Queue
// Name is the name of the state machine.
Name string
// Data to be passed during initialization
Data any
}
Config provides configuration options for state machine initialization.
type DefaultModelFinalizer ¶ added in v1.3.1
type DefaultModelFinalizer struct{}
DefaultModelFinalizer builds the package's runtime dispatch indexes.
func (DefaultModelFinalizer) Finalize ¶ added in v1.3.1
func (DefaultModelFinalizer) Finalize(model *Model) *FinalizedModel
type DefaultModelValidator ¶ added in v1.3.1
type DefaultModelValidator struct{}
DefaultModelValidator runs the package's built-in model validation.
func (DefaultModelValidator) Validate ¶ added in v1.3.1
func (DefaultModelValidator) Validate(model *Model)
type Event ¶
type Event struct {
Kind uint64 `xml:"kind,attr" json:"kind"`
Name string `xml:"name,attr" json:"name"`
ID string `xml:"id,attr" json:"id"`
Source string `xml:"source,attr,omitempty" json:"source,omitempty"`
Target string `xml:"target,attr,omitempty" json:"target,omitempty"`
Data any `xml:"data" json:"data"`
Schema any `xml:"schema" json:"schema"`
}
type EventSnapshot ¶ added in v1.2.0
type EventSnapshot struct {
Name string
Kind uint64 `json:"-"`
Target string
Guard bool
// Schema is copied from model metadata when the snapshot is captured.
// Mutable map, slice, array, pointer, interface, and exported struct fields
// are recursively copied where Go reflection permits.
Schema any
}
type ExpressionFunc ¶ added in v1.0.6
ExpressionFunc is a function type that evaluates a condition on a state machine. Expressions are used for transition guards to determine whether a transition should be taken. They receive the current context, state machine instance, and the triggering event, returning true if the condition is satisfied.
type FinalizedModel ¶ added in v1.3.1
type FinalizedModel struct {
*Model
// contains filtered or unexported fields
}
FinalizedModel is the runtime-ready form of a declarative Model. It owns derived dispatch indexes used by runtime instances.
func Define ¶
func Define[T stringLike](name T, redefinableElements ...RedefinableElement) FinalizedModel
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(hsm.Target("red")),
)
func Redefine ¶ added in v1.3.1
func Redefine(model FinalizedModel, args ...any) FinalizedModel
Redefine replays an existing model under the same root or under a new root name and applies replacement model elements.
func (FinalizedModel) Activities ¶ added in v1.3.1
func (state FinalizedModel) Activities() []string
type Group ¶ added in v1.0.6
type Group struct {
// contains filtered or unexported fields
}
Group is a composite instance that forwards operations to multiple instances. It flattens nested groups and broadcasts events to all members.
func MakeGroup ¶ added in v1.3.0
MakeGroup creates a new group from the provided instances. If the first argument is a string, it is used as the group ID.
func NewGroup ¶ added in v1.0.6
NewGroup creates a new group from the provided instances. Nested groups are flattened.
type Instance ¶
type Instance interface {
// State returns the current state's qualified name.
State() string
Context() context.Context
Clock() Clock
// contains filtered or unexported methods
}
Instance represents an active state machine instance that can process events and track state. It provides methods for event dispatch and state management.
func FromContext ¶
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())
}
func InstancesFromContext ¶
InstancesFromContext retrieves all state machine instances from a context. Returns a slice of instances and a boolean indicating whether any were found. This is useful when multiple state machines share a context and you need to access or iterate over all of them.
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 InlineModel ¶ added in v1.3.1
func InlineModel(redefinableElements ...RedefinableElement) Model
InlineModel creates an anonymous model body for generated submachine composition. Prefer Define for named reusable models.
func (*Model) Activities ¶
func (state *Model) Activities() []string
func (*Model) TransitionSnapshots ¶ added in v1.3.1
func (model *Model) TransitionSnapshots() []TransitionSnapshot
TransitionSnapshots returns a stable snapshot of model transitions.
type ModelFinalizer ¶ added in v1.3.1
type ModelFinalizer interface {
Finalize(model *Model) *FinalizedModel
}
ModelFinalizer prepares a validated model for runtime use.
type ModelFinalizerFunc ¶ added in v1.3.1
type ModelFinalizerFunc func(model *Model) *FinalizedModel
ModelFinalizerFunc adapts a function to ModelFinalizer.
func (ModelFinalizerFunc) Finalize ¶ added in v1.3.1
func (fn ModelFinalizerFunc) Finalize(model *Model) *FinalizedModel
type ModelValidator ¶ added in v1.3.1
type ModelValidator interface {
Validate(model *Model)
}
ModelValidator validates a model after all elements have been applied.
type ModelValidatorFunc ¶ added in v1.3.1
type ModelValidatorFunc func(model *Model)
ModelValidatorFunc adapts a function to ModelValidator.
func (ModelValidatorFunc) Validate ¶ added in v1.3.1
func (fn ModelValidatorFunc) Validate(model *Model)
type ObservationData ¶ added in v1.3.1
ObservationData is the payload for hsm/observation events.
type OperationFunc ¶ added in v1.0.6
OperationFunc is a function type that performs an action on a state machine. Operations are used for state entry/exit behaviors, transition effects, and activity functions. They receive the current context, state machine instance, and the triggering event.
type Queue ¶ added in v1.2.3
type Queue struct {
Push func(ctx context.Context, event Event) error
Pop func(ctx context.Context) (Event, bool, error)
Len func(ctx context.Context) (int, error)
// contains filtered or unexported fields
}
Queue provides injectable buffering for regular state machine events. Push, Pop, and Len are synchronous hooks: each operation must complete and return its event/availability/error directly to the runtime. Completion events are always stored in the runtime-owned LIFO side of Queue and are selected before the configurable regular-event queue.
type RedefinableElement ¶
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(operations ...any) 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(expr any) 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 At ¶ added in v1.1.0
func At(expr any) RedefinableElement
At creates a time-based transition that occurs at a specific timestamp. The timestamp can be dynamically computed based on the state machine's context.
Example:
hsm.Transition(
hsm.At(func(ctx context.Context, hsm *MyHSM, event Event) time.Time {
return time.Now().Add(time.Minute)
}),
hsm.Source("active"),
hsm.Target("timeout")
)
func Attribute ¶ added in v1.0.3
func Attribute[T stringLike](name T, args ...any) RedefinableElement
Attribute declares a model-level attribute with an optional default value. Attributes can be observed via OnSet("name") transitions and updated at runtime via Set / Instance.Set.
func Choice ¶
func Choice[T redefinableOrString](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 DeepHistory ¶ added in v1.0.3
func DeepHistory[T redefinableOrString](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
DeepHistory creates a deep history pseudostate within a composite state. If no history is available, any transitions defined on this pseudostate are used; otherwise the parent state's initial is used.
func Defer ¶
func Defer[T interface {
string | *Event | Event
}](events ...T) RedefinableElement
Defer schedules events to be processed after the current state is exited.
Example:
hsm.Defer(hsm.Event{Name: "event_name"})
func Effect ¶
func Effect(operations ...any) 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(operations ...any) 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 EntryPoint ¶ added in v1.3.1
func EntryPoint[T stringLike](name T, partialElements ...RedefinableElement) RedefinableElement
EntryPoint creates or selects a named submachine entry point. Within a State, it creates a transient vertex with an optional outgoing transition. Within a Transition, it rewrites the transition target to the direct matching entry point on the transition target.
func Every ¶
func Every(expr any) RedefinableElement
Every schedules events to be processed on an interval.
Example:
hsm.Every(func(ctx context.Context, hsm T, event Event) time.Duration {
return time.Second * 30
})
func Exit ¶
func Exit(operations ...any) 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 ExitPoint ¶ added in v1.3.1
func ExitPoint[T stringLike](name T, partialElements ...RedefinableElement) RedefinableElement
ExitPoint creates a transient vertex used to route a submachine outcome to a handler transition on the owning state.
func Final ¶
func Final[T stringLike](name T) 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 Finalizer ¶ added in v1.3.1
func Finalizer(finalizer any) RedefinableElement
Finalizer overrides the model finalizer used while defining or redefining a model.
func Guard ¶
func Guard(expression any) 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(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(hsm.Target("idle")),
)
func Observe ¶ added in v1.3.1
func Observe[T Instance](observer func(context.Context, T, Event), targets ...any) RedefinableElement
Observe attaches an observer to behavior execution and selected transition events.
func On ¶
func On[T interface{ *Event | Event | ~string }](events ...T) RedefinableElement
On defines the events that can cause a transition. Multiple events can be specified for a single transition.
Example:
hsm.Transition(
hsm.On("start", "resume"),
hsm.Source("idle"),
hsm.Target("running")
)
func OnCall ¶ added in v1.0.3
func OnCall[T stringLike](name T) RedefinableElement
OnCall creates a trigger for Call() invocations of the named operation.
func OnSet ¶ added in v1.0.3
func OnSet[T stringLike](name T) RedefinableElement
OnSet creates an attribute-change trigger for the given attribute name. It is the attribute-based equivalent of On(...) and is driven by Set.
func Operation ¶
func Operation[T stringLike](name T, maybeFn ...any) RedefinableElement
Operation declares a named callable for Call()/OnCall(). Supported callables include function values and method expressions.
func ShallowHistory ¶ added in v1.0.3
func ShallowHistory[T redefinableOrString](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
ShallowHistory creates a shallow history pseudostate within a composite state. If no history is available, any transitions defined on this pseudostate are used; otherwise the parent state's initial is used.
func Source ¶
func Source[T redefinableOrString](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[T stringLike](name T, 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 SubmachineState ¶ added in v1.3.1
func SubmachineState[T stringLike, M ComposableModel](name T, machine M, partialElements ...RedefinableElement) RedefinableElement
SubmachineState composes a reusable child model under a state boundary.
func Target ¶
func Target[T redefinableOrString](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 redefinableOrString](nameOrPartialElement T, partialElements ...RedefinableElement) RedefinableElement
Transition creates a new transition between states. Transitions can have events, guards, and effects.
Example:
hsm.Transition(
hsm.On("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 TransitionType ¶ added in v1.3.1
func TransitionType(kindValue uint64) RedefinableElement
TransitionType overrides the transition kind selected during model construction. kindValue must derive from TransitionKind.
func Validator ¶ added in v1.3.1
func Validator(validator any) RedefinableElement
Validator overrides the model validator used while defining or redefining a model.
func When ¶
func When(expr any) RedefinableElement
type Snapshot ¶
type Snapshot struct {
ID string
QualifiedName string
State string
// Attributes is a fresh map whose values are copied from runtime storage.
// Mutating this map, or mutable values reachable only through it, does not
// change the running instance.
Attributes map[string]any
QueueLen int
// Events is a fresh slice for this snapshot. Event schemas follow
// EventSnapshot.Schema copy semantics.
Events []EventSnapshot
Transitions []TransitionSnapshot
}
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
bench_traffic_light
command
|
|
|
conformance
command
|
|
|
kind
module
|
|
|
muid
module
|