Documentation ¶
Overview ¶
Package statemachine provides a convenient implementation of a Finite-state Machine (FSM) in Go. Learn more about FSM on Wikipedia:
https://en.wikipedia.org/wiki/Finite-state_machine
Let's begin with an object that can suitably adopt state machine behaviour:
type Turnstile struct { // Embed the state machine into our turnstile. statemachine.Machine // DisplayMsg stores the text that is displayed to the user. // Contains either "Pay" or "Go". DisplayMsg string } t := &Turnstile{} t.DisplayMsg = "Pay"
Here we're embedding `statemachine.Machine` into our Turnstile struct. Embedding, although not necessary, is a suitable way to apply the state machine behaviour to the struct itself. Turnstile's DisplayMsg variable stores the text that is displayed to the user, and may store either "Pay" or "Go", depending on the state.
Now let's set our state machine's definitions utilizing `MachineBuilder`:
t.BuildNewMachine(func(m statemachine.MachineBuilder) { // States may be pre-defined here. m.States("locked", "unlocked") // Initial State is required to start the state machine. // Setting initial state does not invoke any callbacks. m.InitialState("locked") // Events and their transition(s). m.Event("insertCoin", func(e statemachine.EventBuilder) { e.Transition().From("locked").To("unlocked") }) m.Event("turn", func(e statemachine.EventBuilder) { e.Transition().From("unlocked").To("locked") }) // Transition callbacks. m.AfterTransition().From("locked").To("unlocked").Do(func() { t.DisplayMsg = "Go" }) m.AfterTransition().From("unlocked").To("locked").Do(func() { t.DisplayMsg = "Pay" }) })
Now that our turnstile is ready, let's take it for a spin:
t.StartMachine() fmt.Println(t.State(), t.DisplayMsg) // => locked, Pay err := t.Fire("turn") fmt.Println(err) // => no matching transition for the event fmt.Println(t.State(), t.DisplayMsg) // => locked, Pay t.Fire("insertCoin") fmt.Println(t.State(), t.DisplayMsg) // => unlocked, Go t.Fire("turn") fmt.Println(t.State(), t.DisplayMsg) // => locked, Pay t.StopMachine()
Example (SystemProcess) ¶
package main import ( "log" "github.com/Gurpartap/statemachine-go" ) var processStates = []string{ "unmonitored", "running", "stopped", "starting", "stopping", "restarting", } type ExampleProcess struct { statemachine.Machine IsAutoStartOn bool IsProcessRunning bool } func (p *ExampleProcess) GetIsAutoStartOn() bool { return p.IsAutoStartOn } func (p *ExampleProcess) GetIsProcessRunning() bool { return p.IsProcessRunning } func (ExampleProcess) Start() {} func (ExampleProcess) Stop() {} func (ExampleProcess) Restart() {} func (ExampleProcess) NotifyTriggers(transition statemachine.Transition) {} func (ExampleProcess) RecordTransition(transition statemachine.Transition) {} func (ExampleProcess) LogFailure(err error) { log.Println(err) } func main() { process := &ExampleProcess{} process.Machine = statemachine.BuildNewMachine(func(machineBuilder statemachine.MachineBuilder) { machineBuilder.States(processStates...) machineBuilder.InitialState("unmonitored") machineBuilder.Event("tick", func(eventBuilder statemachine.EventBuilder) { eventBuilder.Transition().From("starting").To("running").If(process.GetIsProcessRunning) eventBuilder.Transition().From("starting").To("stopped").Unless(process.GetIsProcessRunning) // The process failed to die after entering the stopping state. // Change the state to reflect reality. eventBuilder.Transition().From("running").To("stopped").Unless(process.GetIsProcessRunning) eventBuilder.Transition().From("stopping").To("running").If(process.GetIsProcessRunning) eventBuilder.Transition().From("stopping").To("stopped").Unless(process.GetIsProcessRunning) eventBuilder.Transition().From("stopped").To("running").If(process.GetIsProcessRunning) eventBuilder.Transition().From("stopped").To("starting").If(func(transition statemachine.Transition) bool { return process.GetIsAutoStartOn() && !process.GetIsProcessRunning() }) eventBuilder.Transition().From("restarting").To("running").If(process.GetIsProcessRunning) eventBuilder.Transition().From("restarting").To("stopped").Unless(process.GetIsProcessRunning) }) machineBuilder.Event("monitor", func(eventBuilder statemachine.EventBuilder) { eventBuilder.Transition().From("unmonitored").To("stopped") }) machineBuilder.Event("start", func(eventBuilder statemachine.EventBuilder) { eventBuilder.Transition().From("unmonitored", "stopped").To("starting") }) machineBuilder.Event("stop", func(eventBuilder statemachine.EventBuilder) { eventBuilder.Transition().From("running").To("stopping") }) machineBuilder.Event("restart", func(eventBuilder statemachine.EventBuilder) { eventBuilder.Transition().From("running", "stopped").To("restarting") }) machineBuilder.Event("unmonitor", func(eventBuilder statemachine.EventBuilder) { eventBuilder.Transition().FromAny().To("unmonitored") }) machineBuilder.BeforeTransition().To("starting").Do(func() { process.IsAutoStartOn = true }) machineBuilder.AfterTransition().To("starting").Do(func() { process.Start() }) machineBuilder.BeforeTransition().To("stopping").Do(func() { process.IsAutoStartOn = false }) machineBuilder.AfterTransition().To("stopping").Do(func() { process.Stop() }) machineBuilder.BeforeTransition().To("restarting").Do(func() { process.IsAutoStartOn = true }) machineBuilder.AfterTransition().To("restarting").Do(func() { process.Restart() }) machineBuilder.BeforeTransition().To("unmonitored").Do(func() { process.IsAutoStartOn = false }) machineBuilder.BeforeTransition().Any().Do(process.NotifyTriggers) machineBuilder.AfterTransition().Any().Do(process.RecordTransition) machineBuilder.AfterFailure().OnAnyEvent().Do(process.LogFailure) }) }
Output:
Index ¶
- Variables
- type ChoiceBuilder
- type ChoiceCondition
- type ChoiceConditionDef
- type ChoiceDef
- func (def *ChoiceDef) SetCondition(condition ChoiceCondition)
- func (def *ChoiceDef) SetLabel(label string)
- func (def *ChoiceDef) SetOnFalse(eventBuilderFn func(eventBuilder EventBuilder))
- func (def *ChoiceDef) SetOnTrue(eventBuilderFn func(eventBuilder EventBuilder))
- func (def *ChoiceDef) SetUnlessGuard(guard TransitionGuard)
- type ChoiceFalseBuilder
- type ChoiceTrueBuilder
- type Event
- type EventBuildable
- type EventBuilder
- type EventCallbackBuilder
- type EventCallbackDef
- type EventCallbackFunc
- type EventCallbackFuncDef
- type EventCallbackOnBuilder
- type EventDef
- type Machine
- type MachineBuildable
- type MachineBuilder
- type MachineDef
- func (def *MachineDef) AddAfterCallback(CallbackDef *TransitionCallbackDef)
- func (def *MachineDef) AddAroundCallback(CallbackDef *TransitionCallbackDef)
- func (def *MachineDef) AddBeforeCallback(CallbackDef *TransitionCallbackDef)
- func (def *MachineDef) AddEvent(event string, eventDef *EventDef)
- func (def *MachineDef) AddFailureCallback(CallbackDef *EventCallbackDef)
- func (def *MachineDef) SetID(id string)
- func (def *MachineDef) SetInitialState(state string)
- func (def *MachineDef) SetStates(states ...string)
- func (def *MachineDef) SetSubmachine(state string, submachine *MachineDef)
- type Message
- type OverrideState
- type StateMap
- type Transition
- type TransitionAndGuardBuilder
- type TransitionBuilder
- type TransitionCallbackBuilder
- type TransitionCallbackDef
- func (s *TransitionCallbackDef) AddCallbackFunc(callbackFuncs ...TransitionCallbackFunc)
- func (s *TransitionCallbackDef) Matches(from, to string) bool
- func (s *TransitionCallbackDef) SetExitToState(supermachineState string)
- func (s *TransitionCallbackDef) SetFrom(states ...string)
- func (s *TransitionCallbackDef) SetFromAnyExcept(exceptStates ...string)
- func (s *TransitionCallbackDef) SetSame()
- func (s *TransitionCallbackDef) SetTo(states ...string)
- func (s *TransitionCallbackDef) SetToAnyExcept(exceptStates ...string)
- type TransitionCallbackDoBuilder
- type TransitionCallbackExceptFromBuilder
- type TransitionCallbackFromBuilder
- type TransitionCallbackFunc
- type TransitionCallbackFuncDef
- type TransitionCallbackToBuilder
- type TransitionDef
- func (def *TransitionDef) AddIfGuard(guards ...TransitionGuard)
- func (def *TransitionDef) AddUnlessGuard(guards ...TransitionGuard)
- func (def *TransitionDef) IsAllowed(fromState string, machine Machine) bool
- func (def *TransitionDef) Matches(matchFrom string) bool
- func (def *TransitionDef) SetFrom(states ...string)
- func (def *TransitionDef) SetFromAnyExcept(exceptStates ...string)
- func (def *TransitionDef) SetTo(state string)
- type TransitionExceptFromBuilder
- type TransitionFromBuilder
- type TransitionGuard
- type TransitionGuardDef
- type TransitionToBuilder
- type TriggerEvent
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNoMatchingTransition = errors.New("no matching transition")
var ErrStateTypeNotSupported = errors.New("state type not supported")
var ErrTransitionNotAllowed = errors.New("transition not allowed")
Functions ¶
This section is empty.
Types ¶
type ChoiceBuilder ¶
type ChoiceBuilder interface { Label(label string) ChoiceBuilder Unless(guard TransitionGuard) ChoiceBuilder OnTrue(eventBuilderFn func(eventBuilder EventBuilder)) ChoiceTrueBuilder OnFalse(eventBuilderFn func(eventBuilder EventBuilder)) ChoiceFalseBuilder }
ChoiceBuilder provides the ability to define the conditions and result handling of the choice definition.
type ChoiceCondition ¶
type ChoiceCondition interface{}
ChoiceCondition may accept Transition object as input, and it must return a bool type.
Valid ChoiceCondition types:
bool func() bool func(transition statemachine.Transition) bool
type ChoiceConditionDef ¶
type ChoiceConditionDef struct { Label string `json:",omitempty" hcl:"label" hcle:"omitempty"` RegisteredFunc string `json:",omitempty" hcl:"registered_func" hcle:"omitempty"` Condition ChoiceCondition `json:"-" hcle:"omit"` }
type ChoiceDef ¶
type ChoiceDef struct { Condition *ChoiceConditionDef `json:",omitempty" hcl:"condition" hcle:"omitempty"` UnlessGuard *TransitionGuardDef `json:",omitempty" hcl:"unless_condition" hcle:"omitempty"` OnTrue *EventDef `json:",omitempty" hcl:"on_true" hcle:"omitempty"` OnFalse *EventDef `json:",omitempty" hcl:"on_false" hcle:"omitempty"` }
func (*ChoiceDef) SetCondition ¶
func (def *ChoiceDef) SetCondition(condition ChoiceCondition)
func (*ChoiceDef) SetOnFalse ¶
func (def *ChoiceDef) SetOnFalse(eventBuilderFn func(eventBuilder EventBuilder))
func (*ChoiceDef) SetOnTrue ¶
func (def *ChoiceDef) SetOnTrue(eventBuilderFn func(eventBuilder EventBuilder))
func (*ChoiceDef) SetUnlessGuard ¶
func (def *ChoiceDef) SetUnlessGuard(guard TransitionGuard)
type ChoiceFalseBuilder ¶
type ChoiceFalseBuilder interface {
OnTrue(eventBuilderFn func(eventBuilder EventBuilder))
}
ChoiceFalseBuilder inherits from ChoiceBuilder
type ChoiceTrueBuilder ¶
type ChoiceTrueBuilder interface {
OnFalse(eventBuilderFn func(eventBuilder EventBuilder))
}
ChoiceTrueBuilder inherits from ChoiceBuilder
type Event ¶
type Event interface {
Event() string
}
Event provides methods for accessing useful information about the active event.
type EventBuildable ¶
EventBuildable implementation is able to consume the result of building features from EventBuilder. EventBuildable is oblivious to Event or it's implementation.
type EventBuilder ¶
type EventBuilder interface { TimedEvery(duration time.Duration) EventBuilder // TODO: Assert that Choice(...) and Transition() are not used together. Choice(condition ChoiceCondition) ChoiceBuilder // Transition begins the transition builder, accepting states and guards. Transition() TransitionBuilder // Build plugs the collected feature definitions into any object // that understands them (implements dsl.EventBuildable). Use this method // if you're not using MachineBuilder.Event() to define the event. Build(event EventBuildable) }
EventBuilder provides the ability to define an event along with its transitions and their guards. EventBuilder is oblivious to Event or it's implementation.
func NewEventBuilder ¶
func NewEventBuilder(name string) EventBuilder
NewEventBuilder returns a zero-valued instance of eventBuilder, which implements EventBuilder.
Example ¶
p := &ExampleProcess{} p.Machine = statemachine.NewMachine() machineBuilder := statemachine.NewMachineBuilder() machineBuilder.States(processStates...) machineBuilder.InitialState("unmonitored") eventBuilder := statemachine.NewEventBuilder("monitor") eventBuilder.Transition().From("unmonitored").To("stopped") eventBuilder.Build(machineBuilder) machineBuilder.Build(p.Machine) fmt.Println(p.Machine.GetState()) if err := p.Machine.Fire("monitor"); err != nil { fmt.Println(err) } fmt.Println(p.Machine.GetState()) if err := p.Machine.Fire("monitor"); err != nil { fmt.Println(err) }
Output: unmonitored stopped no matching transition
type EventCallbackBuilder ¶
type EventCallbackBuilder interface { On(events ...string) EventCallbackOnBuilder OnAnyEvent() EventCallbackOnBuilder OnAnyEventExcept(events ...string) EventCallbackOnBuilder }
EventCallbackBuilder provides the ability to define the `on` event(s) of the event callback matcher.
type EventCallbackDef ¶
type EventCallbackDef struct { On []string `json:",omitempty" hcl:"on" hcle:"omitempty"` ExceptOn []string `json:",omitempty" hcl:"except_on" hcle:"omitempty"` Do []*EventCallbackFuncDef `json:",omitempty" hcl:"do" hcle:"omitempty"` // contains filtered or unexported fields }
func (*EventCallbackDef) AddCallbackFunc ¶
func (s *EventCallbackDef) AddCallbackFunc(callbackFunc EventCallbackFunc)
func (*EventCallbackDef) MatchesEvent ¶
func (s *EventCallbackDef) MatchesEvent(event string) bool
func (*EventCallbackDef) SetOn ¶
func (s *EventCallbackDef) SetOn(events ...string)
func (*EventCallbackDef) SetOnAnyEventExcept ¶
func (s *EventCallbackDef) SetOnAnyEventExcept(exceptEvents ...string)
type EventCallbackFunc ¶
type EventCallbackFunc interface{}
EventCallbackFunc is a func with dynamic args. Any callback func of this type may accept a Transition object as input. Return values will be ignored.
For AfterFailure callback, it must accept an `error` type arg:
func(err error) func(transition eventmachine.Transition, err error)
type EventCallbackFuncDef ¶
type EventCallbackFuncDef struct { RegisteredFunc string `json:",omitempty" hcl:"registered_func" hcle:"omitempty"` Func EventCallbackFunc `json:"-" hcle:"omit"` }
type EventCallbackOnBuilder ¶
type EventCallbackOnBuilder interface {
Do(callbackFunc EventCallbackFunc) EventCallbackOnBuilder
}
EventCallbackOnBuilder inherits from EventCallbackBuilder (or EventCallbackExceptFromBuilder) and provides the ability to define the transition callback func.
type EventDef ¶
type EventDef struct { // Name string TimedEvery time.Duration `json:",omitempty" hcl:"timed_every" hcle:"omitempty"` Choice *ChoiceDef `json:",omitempty" hcl:"choice" hcle:"omitempty"` Transitions []*TransitionDef `json:",omitempty" hcl:"transitions" hcle:"omitempty"` }
func (*EventDef) AddTransition ¶
func (def *EventDef) AddTransition(transitionDef *TransitionDef)
type Machine ¶
type Machine interface { Build(machineBuilderFn func(machineBuilder MachineBuilder)) SetMachineDef(def *MachineDef) GetStateMap() StateMap GetState() string SetCurrentState(state interface{}) error IsState(state string) bool Submachine(idPath ...string) (Machine, error) Fire(event string) error Send(signal Message) error }
Machine provides a public interface to the state machine implementation. It provides methods to build and access features of the state machine.
func BuildNewMachine ¶
func BuildNewMachine(machineBuilderFn func(machineBuilder MachineBuilder)) Machine
BuildNewMachine creates a zero-valued instance of machine, and builds it using the passed machineBuilderFn arg.
Example ¶
p := &ExampleProcess{} p.Machine = statemachine.BuildNewMachine(func(m statemachine.MachineBuilder) { m.States(processStates...) m.InitialState("unmonitored") // ... }) fmt.Println(p.Machine.GetState())
Output: unmonitored
func NewMachine ¶
func NewMachine() Machine
NewMachine returns a zero-valued instance of machine, which implements Machine.
Example ¶
p := &ExampleProcess{} p.Machine = statemachine.NewMachine() p.Machine.Build(func(m statemachine.MachineBuilder) { m.States(processStates...) m.InitialState("unmonitored") // ... }) fmt.Println(p.Machine.GetState())
Output: unmonitored
type MachineBuildable ¶
type MachineBuildable interface {
SetMachineDef(def *MachineDef)
}
MachineBuildable implementation is able to consume the result of building features from dsl.MachineBuilder. MachineBuildable is oblivious to Machine or it's implementation.
type MachineBuilder ¶
type MachineBuilder interface { // Build plugs the collected feature definitions into any object // that understands them (implements MachineBuildable). Use this method // if you're not using Machine.Build() to define the state machine. Build(machine MachineBuildable) SetEventDef(event string, def *EventDef) ID(id string) // States pre-defines the set of known states. This is optional because // all known states will be identified from other definitions. States(states ...string) // InitialState defines the state that the machine initializes with. // Initial state must be defined for every state machine. InitialState(state string) Submachine(state string, submachineBuilderFn func(submachineBuilder MachineBuilder)) // Event provides the ability to define possible transitions for an event. Event(name string, eventBuilderFn ...func(eventBuilder EventBuilder)) EventBuilder BeforeTransition() TransitionCallbackBuilder AroundTransition() TransitionCallbackBuilder AfterTransition() TransitionCallbackBuilder AfterFailure() EventCallbackBuilder }
MachineBuilder provides the ability to define all features of the state machine, including states, events, event transitions, and transition callbacks. MachineBuilder is oblivious to Machine or it's implementation.
func NewMachineBuilder ¶
func NewMachineBuilder() MachineBuilder
NewMachineBuilder returns a zero-valued instance of machineBuilder, which implements MachineBuilder.
Example ¶
machineBuilder := statemachine.NewMachineBuilder() machineBuilder.States(processStates...) machineBuilder.InitialState("unmonitored") machineBuilder.Event("monitor", func(e statemachine.EventBuilder) { e.Transition().From("unmonitored").To("stopped") }) machineBuilder.Event("unmonitor", func(e statemachine.EventBuilder) { e.Transition().FromAny().To("unmonitored") }) p := &ExampleProcess{} p.Machine = statemachine.NewMachine() machineBuilder.Build(p.Machine) fmt.Println(p.Machine.GetState()) if err := p.Machine.Fire("monitor"); err != nil { fmt.Println(err) } fmt.Println(p.Machine.GetState()) if err := p.Machine.Fire("unmonitor"); err != nil { fmt.Println(err) } fmt.Println(p.Machine.GetState())
Output: unmonitored stopped unmonitored
type MachineDef ¶
type MachineDef struct { ID string `json:"id,omitempty" hcl:"id" hcle:"omitempty"` States []string `hcl:"states"` InitialState string `hcl:"initial_state"` Events map[string]*EventDef `json:",omitempty" hcl:"event" hcle:"omitempty"` Submachines map[string][]*MachineDef `json:",omitempty" hcl:"submachine" hcle:"omitempty"` BeforeCallbacks []*TransitionCallbackDef `json:",omitempty" hcl:"before_callbacks" hcle:"omitempty"` AroundCallbacks []*TransitionCallbackDef `json:",omitempty" hcl:"around_callbacks" hcle:"omitempty"` AfterCallbacks []*TransitionCallbackDef `json:",omitempty" hcl:"after_callbacks" hcle:"omitempty"` FailureCallbacks []*EventCallbackDef `json:",omitempty" hcl:"failure_callbacks" hcle:"omitempty"` }
Example ¶
// statemachine.RegisterFunc("after-callback-1", func() { // fmt.Printf("after callback\n") // }) machineDef := &statemachine.MachineDef{ States: processStates, InitialState: "unmonitored", Submachines: map[string][]*statemachine.MachineDef{ "running": { { InitialState: "pending", AfterCallbacks: []*statemachine.TransitionCallbackDef{ {To: []string{"success"}, ExitToState: "stopped"}, {To: []string{"failure"}, ExitToState: "restarting"}, }, }, }, }, Events: map[string]*statemachine.EventDef{ "monitor": { Transitions: []*statemachine.TransitionDef{{From: []string{"unmonitored"}, To: "stopped"}}, }, "unmonitor": { Transitions: []*statemachine.TransitionDef{{To: "unmonitored"}}, }, }, AfterCallbacks: []*statemachine.TransitionCallbackDef{ { Do: []*statemachine.TransitionCallbackFuncDef{ // { // RegisteredFunc: "after-callback-1", // }, { Func: func() { fmt.Printf("after callback\n") }, }, }, }, }, } p := &ExampleProcess{} p.Machine = statemachine.NewMachine() p.Machine.SetMachineDef(machineDef) fmt.Println(p.Machine.GetState()) if err := p.Machine.Fire("monitor"); err != nil { fmt.Println(err) } fmt.Println(p.Machine.GetState()) if err := p.Machine.Fire("unmonitor"); err != nil { fmt.Println(err) } fmt.Println(p.Machine.GetState())
Output: unmonitored after callback stopped after callback unmonitored
func NewMachineDef ¶
func NewMachineDef() *MachineDef
func (*MachineDef) AddAfterCallback ¶
func (def *MachineDef) AddAfterCallback(CallbackDef *TransitionCallbackDef)
func (*MachineDef) AddAroundCallback ¶
func (def *MachineDef) AddAroundCallback(CallbackDef *TransitionCallbackDef)
func (*MachineDef) AddBeforeCallback ¶
func (def *MachineDef) AddBeforeCallback(CallbackDef *TransitionCallbackDef)
func (*MachineDef) AddEvent ¶
func (def *MachineDef) AddEvent(event string, eventDef *EventDef)
func (*MachineDef) AddFailureCallback ¶
func (def *MachineDef) AddFailureCallback(CallbackDef *EventCallbackDef)
func (*MachineDef) SetID ¶
func (def *MachineDef) SetID(id string)
func (*MachineDef) SetInitialState ¶
func (def *MachineDef) SetInitialState(state string)
func (*MachineDef) SetStates ¶
func (def *MachineDef) SetStates(states ...string)
func (*MachineDef) SetSubmachine ¶
func (def *MachineDef) SetSubmachine(state string, submachine *MachineDef)
type OverrideState ¶
type OverrideState struct {
State interface{}
}
func (OverrideState) Value ¶
func (e OverrideState) Value() interface{}
type Transition ¶
Transition provides methods for accessing useful information about the active transition.
type TransitionAndGuardBuilder ¶
type TransitionAndGuardBuilder interface { Label(label string) TransitionAndGuardBuilder AndIf(guards ...TransitionGuard) TransitionAndGuardBuilder AndUnless(guards ...TransitionGuard) TransitionAndGuardBuilder }
TransitionAndGuardBuilder inherits from TransitionToBuilder and provides the ability to define additional guard condition funcs for the transition.
type TransitionBuilder ¶
type TransitionBuilder interface { From(states ...string) TransitionFromBuilder FromAny() TransitionFromBuilder FromAnyExcept(states ...string) TransitionFromBuilder }
TransitionBuilder provides the ability to define the `from` state(s) of the transition matcher.
type TransitionCallbackBuilder ¶
type TransitionCallbackBuilder interface { From(states ...string) TransitionCallbackFromBuilder FromAny() TransitionCallbackFromBuilder FromAnyExcept(states ...string) TransitionCallbackFromBuilder To(states ...string) TransitionCallbackToBuilder ToAnyExcept(states ...string) TransitionCallbackToBuilder Any() TransitionCallbackToBuilder }
TransitionCallbackBuilder provides the ability to define the `from` state(s) of the transition callback matcher.
type TransitionCallbackDef ¶
type TransitionCallbackDef struct { From []string `json:",omitempty" hcl:"from" hcle:"omitempty"` ExceptFrom []string `json:",omitempty" hcl:"except_from" hcle:"omitempty"` To []string `json:",omitempty" hcl:"to" hcle:"omitempty"` ExceptTo []string `json:",omitempty" hcl:"except_to" hcle:"omitempty"` Do []*TransitionCallbackFuncDef `json:",omitempty" hcl:"do" hcle:"omitempty"` ExitToState string `json:",omitempty" hcl:"exit_to_state" hcle:"omitempty"` // contains filtered or unexported fields }
func (*TransitionCallbackDef) AddCallbackFunc ¶
func (s *TransitionCallbackDef) AddCallbackFunc(callbackFuncs ...TransitionCallbackFunc)
func (*TransitionCallbackDef) Matches ¶
func (s *TransitionCallbackDef) Matches(from, to string) bool
func (*TransitionCallbackDef) SetExitToState ¶
func (s *TransitionCallbackDef) SetExitToState(supermachineState string)
func (*TransitionCallbackDef) SetFrom ¶
func (s *TransitionCallbackDef) SetFrom(states ...string)
func (*TransitionCallbackDef) SetFromAnyExcept ¶
func (s *TransitionCallbackDef) SetFromAnyExcept(exceptStates ...string)
func (*TransitionCallbackDef) SetSame ¶
func (s *TransitionCallbackDef) SetSame()
func (*TransitionCallbackDef) SetTo ¶
func (s *TransitionCallbackDef) SetTo(states ...string)
func (*TransitionCallbackDef) SetToAnyExcept ¶
func (s *TransitionCallbackDef) SetToAnyExcept(exceptStates ...string)
type TransitionCallbackDoBuilder ¶
type TransitionCallbackDoBuilder interface {
Label(label string) TransitionCallbackToBuilder
}
type TransitionCallbackExceptFromBuilder ¶
type TransitionCallbackExceptFromBuilder interface { To(states ...string) TransitionCallbackToBuilder ToSame() TransitionCallbackToBuilder ToAny() TransitionCallbackToBuilder ToAnyExcept(states ...string) TransitionCallbackToBuilder ToAnyExceptSame() TransitionCallbackToBuilder }
TransitionCallbackExceptFromBuilder inherits `from` states from TransitionCallbackBuilder and provides the ability to define the `to` states of the transition callback matcher.
type TransitionCallbackFromBuilder ¶
type TransitionCallbackFromBuilder interface { ExceptFrom(states ...string) TransitionCallbackExceptFromBuilder To(states ...string) TransitionCallbackToBuilder ToSame() TransitionCallbackToBuilder ToAny() TransitionCallbackToBuilder ToAnyExcept(states ...string) TransitionCallbackToBuilder ToAnyExceptSame() TransitionCallbackToBuilder }
TransitionCallbackFromBuilder inherits `from` states from TransitionCallbackBuilder and provides the ability to define the `except from` and `to` states of the transition callback matcher.
type TransitionCallbackFunc ¶
type TransitionCallbackFunc interface{}
TransitionCallbackFunc is a func with dynamic args. Any callback func of this type may accept a Machine and/or Transition object as inputs. Return values will be ignored.
For BeforeTransition and AfterTransition:
func() func(machine statemachine.Machine) func(transition statemachine.Transition) func(machine statemachine.Machine, transition statemachine.Transition)
For AroundTransition callback, it must accept a `func()` type arg. The callback must call `next()` to continue the transition.
func(next func()) func(machine statemachine.Machine, next func()) func(transition statemachine.Transition, next func()) func(machine statemachine.Machine, transition statemachine.Transition, next func())
For AfterFailure callback, it must accept an `error` type arg:
func(err error) func(machine statemachine.Machine, err error) func(transition statemachine.Transition, err error) func(machine statemachine.Machine, transition statemachine.Transition, err error)
TODO: perhaps support a Service interface struct, with methods to listen
for state changes. a service may be useful to implement [interruptible] long-running callbacks. example: a download in a download manager.
type TransitionCallbackFuncDef ¶
type TransitionCallbackFuncDef struct { Label string `json:",omitempty" hcl:"label" hcle:"omitempty"` RegisteredFunc string `json:",omitempty" hcl:"registered_func" hcle:"omitempty"` Func TransitionCallbackFunc `json:"-" hcle:"omit"` }
type TransitionCallbackToBuilder ¶
type TransitionCallbackToBuilder interface { ExitToState(supermachineState string) Do(callbackFuncs ...TransitionCallbackFunc) TransitionCallbackDoBuilder }
TransitionCallbackToBuilder inherits from TransitionCallbackBuilder (or TransitionCallbackExceptFromBuilder) and provides the ability to define the transition callback func.
type TransitionDef ¶
type TransitionDef struct { From []string `json:",omitempty" hcl:"from" hcle:"omitempty"` ExceptFrom []string `json:",omitempty" hcl:"except_from" hcle:"omitempty"` To string `hcl:"to"` IfGuards []*TransitionGuardDef `json:",omitempty" hcl:"if_guard" hcle:"omitempty"` UnlessGuards []*TransitionGuardDef `json:",omitempty" hcl:"unless_guard" hcle:"omitempty"` }
func (*TransitionDef) AddIfGuard ¶
func (def *TransitionDef) AddIfGuard(guards ...TransitionGuard)
func (*TransitionDef) AddUnlessGuard ¶
func (def *TransitionDef) AddUnlessGuard(guards ...TransitionGuard)
func (*TransitionDef) IsAllowed ¶
func (def *TransitionDef) IsAllowed(fromState string, machine Machine) bool
func (*TransitionDef) Matches ¶
func (def *TransitionDef) Matches(matchFrom string) bool
func (*TransitionDef) SetFrom ¶
func (def *TransitionDef) SetFrom(states ...string)
func (*TransitionDef) SetFromAnyExcept ¶
func (def *TransitionDef) SetFromAnyExcept(exceptStates ...string)
func (*TransitionDef) SetTo ¶
func (def *TransitionDef) SetTo(state string)
type TransitionExceptFromBuilder ¶
type TransitionExceptFromBuilder interface {
To(state string) TransitionToBuilder
}
TransitionExceptFromBuilder inherits from TransitionFromBuilder and provides the ability to define the `to` state of the transition matcher.
type TransitionFromBuilder ¶
type TransitionFromBuilder interface { ExceptFrom(states ...string) TransitionExceptFromBuilder To(state string) TransitionToBuilder }
TransitionFromBuilder inherits `from` states from TransitionBuilder and provides the ability to define the `to` state as well as the `except from` states of the transition matcher.
type TransitionGuard ¶
type TransitionGuard interface{}
TransitionGuard may accept Transition object as input, and it must return a bool type.
Valid TransitionGuard types:
bool func() bool func(transition statemachine.Transition) bool
type TransitionGuardDef ¶
type TransitionGuardDef struct { Label string `json:",omitempty" hcl:"label" hcle:"omitempty"` RegisteredFunc string `json:",omitempty" hcl:"registered_func" hcle:"omitempty"` Guard TransitionGuard `json:"-" hcle:"omit"` }
type TransitionToBuilder ¶
type TransitionToBuilder interface { If(guards ...TransitionGuard) TransitionAndGuardBuilder Unless(guards ...TransitionGuard) TransitionAndGuardBuilder }
TransitionToBuilder inherits from TransitionFromBuilder (or TransitionExceptFromBuilder) and provides the ability to define the guard condition funcs for the transition.
type TriggerEvent ¶
type TriggerEvent struct {
Event string
}
func (TriggerEvent) Value ¶
func (e TriggerEvent) Value() interface{}
Source Files ¶
- choice_builder.go
- choice_def.go
- doc.go
- error.go
- event.go
- event_builder.go
- event_callback_builder.go
- event_callback_def.go
- event_def.go
- event_impl.go
- machine.go
- machine_builder.go
- machine_def.go
- machine_impl.go
- message.go
- transition.go
- transition_builder.go
- transition_callback_builder.go
- transition_callback_def.go
- transition_def.go
- transition_impl.go