Documentation ¶
Overview ¶
Example ¶
package main import ( "context" "fmt" "reflect" "github.com/gustavoaborges/stateless" ) const ( triggerCallDialed = "CallDialed" triggerCallConnected = "CallConnected" triggerLeftMessage = "LeftMessage" triggerPlacedOnHold = "PlacedOnHold" triggerTakenOffHold = "TakenOffHold" triggerPhoneHurledAgainstWall = "PhoneHurledAgainstWall" triggerMuteMicrophone = "MuteMicrophone" triggerUnmuteMicrophone = "UnmuteMicrophone" triggerSetVolume = "SetVolume" ) const ( stateOffHook = "OffHook" stateRinging = "Ringing" stateConnected = "Connected" stateOnHold = "OnHold" statePhoneDestroyed = "PhoneDestroyed" ) func main() { phoneCall := stateless.NewStateMachine(stateOffHook) phoneCall.SetTriggerParameters(triggerSetVolume, reflect.TypeOf(0)) phoneCall.SetTriggerParameters(triggerCallDialed, reflect.TypeOf("")) phoneCall.Configure(stateOffHook). Permit(triggerCallDialed, stateRinging) phoneCall.Configure(stateRinging). OnEntryFrom(triggerCallDialed, func(_ context.Context, args ...interface{}) error { onDialed(args[0].(string)) return nil }). Permit(triggerCallConnected, stateConnected) phoneCall.Configure(stateConnected). OnEntry(startCallTimer). OnExit(func(_ context.Context, _ ...interface{}) error { stopCallTimer() return nil }). InternalTransition(triggerMuteMicrophone, func(_ context.Context, _ ...interface{}) error { onMute() return nil }). InternalTransition(triggerUnmuteMicrophone, func(_ context.Context, _ ...interface{}) error { onUnmute() return nil }). InternalTransition(triggerSetVolume, func(_ context.Context, args ...interface{}) error { onSetVolume(args[0].(int)) return nil }). Permit(triggerLeftMessage, stateOffHook). Permit(triggerPlacedOnHold, stateOnHold) phoneCall.Configure(stateOnHold). SubstateOf(stateConnected). Permit(triggerTakenOffHold, stateConnected). Permit(triggerPhoneHurledAgainstWall, statePhoneDestroyed) phoneCall.ToGraph() phoneCall.Fire(triggerCallDialed, "gustavoaborges") phoneCall.Fire(triggerCallConnected) phoneCall.Fire(triggerSetVolume, 2) phoneCall.Fire(triggerPlacedOnHold) phoneCall.Fire(triggerMuteMicrophone) phoneCall.Fire(triggerUnmuteMicrophone) phoneCall.Fire(triggerTakenOffHold) phoneCall.Fire(triggerSetVolume, 11) phoneCall.Fire(triggerPlacedOnHold) phoneCall.Fire(triggerPhoneHurledAgainstWall) fmt.Printf("State is %v\n", phoneCall.MustState()) } func onSetVolume(volume int) { fmt.Printf("Volume set to %d!\n", volume) } func onUnmute() { fmt.Println("Microphone unmuted!") } func onMute() { fmt.Println("Microphone muted!") } func onDialed(callee string) { fmt.Printf("[Phone Call] placed for : [%s]\n", callee) } func startCallTimer(_ context.Context, _ ...interface{}) error { fmt.Println("[Timer:] Call started at 11:00am") return nil } func stopCallTimer() { fmt.Println("[Timer:] Call ended at 11:30am") }
Output: [Phone Call] placed for : [gustavoaborges] [Timer:] Call started at 11:00am Volume set to 2! Microphone muted! Microphone unmuted! Volume set to 11! [Timer:] Call ended at 11:30am State is PhoneDestroyed
Index ¶
- func DefaultUnhandledTriggerAction(_ context.Context, state State, trigger Trigger, unmetGuards []string) error
- type ActionFunc
- type DestinationSelectorFunc
- type FiringMode
- type GuardFunc
- type PossibleTrigger
- type State
- type StateConfiguration
- func (sc *StateConfiguration) Ignore(trigger Trigger, guards ...GuardFunc) *StateConfiguration
- func (sc *StateConfiguration) InitialTransition(targetState State) *StateConfiguration
- func (sc *StateConfiguration) InternalTransition(trigger Trigger, action ActionFunc, guards ...GuardFunc) *StateConfiguration
- func (sc *StateConfiguration) Machine() *StateMachine
- func (sc *StateConfiguration) OnActive(action func(context.Context) error) *StateConfiguration
- func (sc *StateConfiguration) OnDeactivate(action func(context.Context) error) *StateConfiguration
- func (sc *StateConfiguration) OnEntry(action ActionFunc) *StateConfiguration
- func (sc *StateConfiguration) OnEntryFrom(trigger Trigger, action ActionFunc) *StateConfiguration
- func (sc *StateConfiguration) OnExit(action ActionFunc) *StateConfiguration
- func (sc *StateConfiguration) Permit(trigger Trigger, destinationState State, guards ...GuardFunc) *StateConfiguration
- func (sc *StateConfiguration) PermitDynamic(trigger Trigger, selector DestinationSelectorFunc, guards ...GuardFunc) *StateConfiguration
- func (sc *StateConfiguration) PermitReentry(trigger Trigger, guards ...GuardFunc) *StateConfiguration
- func (sc *StateConfiguration) State() State
- func (sc *StateConfiguration) SubstateOf(superstate State) *StateConfiguration
- type StateMachine
- func (sm *StateMachine) Activate() error
- func (sm *StateMachine) ActivateCtx(ctx context.Context) error
- func (sm *StateMachine) CanFire(trigger Trigger, args ...interface{}) (bool, error)
- func (sm *StateMachine) CanFireCtx(ctx context.Context, trigger Trigger, args ...interface{}) (bool, error)
- func (sm *StateMachine) Configure(state State) *StateConfiguration
- func (sm *StateMachine) Deactivate() error
- func (sm *StateMachine) DeactivateCtx(ctx context.Context) error
- func (sm *StateMachine) Fire(trigger Trigger, args ...interface{}) error
- func (sm *StateMachine) FireCtx(ctx context.Context, trigger Trigger, args ...interface{}) error
- func (sm *StateMachine) Firing() bool
- func (sm *StateMachine) IsInState(state State) (bool, error)
- func (sm *StateMachine) IsInStateCtx(ctx context.Context, state State) (bool, error)
- func (sm *StateMachine) MustState() State
- func (sm *StateMachine) OnTransitioned(fn ...TransitionFunc)
- func (sm *StateMachine) OnTransitioning(fn ...TransitionFunc)
- func (sm *StateMachine) OnUnhandledTrigger(fn UnhandledTriggerActionFunc)
- func (sm *StateMachine) PermittedTriggers(args ...interface{}) ([]Trigger, error)
- func (sm *StateMachine) PermittedTriggersCtx(ctx context.Context, args ...interface{}) ([]Trigger, error)
- func (sm *StateMachine) PossibleTriggers(args ...interface{}) ([]PossibleTrigger, error)
- func (sm *StateMachine) PossibleTriggersCtx(ctx context.Context, args ...interface{}) ([]PossibleTrigger, error)
- func (sm *StateMachine) SetTriggerParameters(trigger Trigger, argumentTypes ...reflect.Type)
- func (sm *StateMachine) State(ctx context.Context) (State, error)
- func (sm *StateMachine) String() string
- func (sm *StateMachine) ToGraph() string
- type Transition
- type TransitionFunc
- type Trigger
- type UnhandledTriggerActionFunc
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type ActionFunc ¶
ActionFunc describes a generic action function. The context will always contain Transition information.
type DestinationSelectorFunc ¶ added in v1.5.4
DestinationSelectorFunc defines a functions that is called to select a dynamic destination.
type FiringMode ¶
type FiringMode uint8
FiringMode enumerate the different modes used when Fire-ing a trigger.
const ( // FiringQueued mode shoud be used when run-to-completion is required. This is the recommended mode. FiringQueued FiringMode = iota // FiringImmediate should be used when the queing of trigger events are not needed. // Care must be taken when using this mode, as there is no run-to-completion guaranteed. FiringImmediate )
type PossibleTrigger ¶
type StateConfiguration ¶
type StateConfiguration struct {
// contains filtered or unexported fields
}
StateConfiguration is the configuration for a single state value.
func (*StateConfiguration) Ignore ¶
func (sc *StateConfiguration) Ignore(trigger Trigger, guards ...GuardFunc) *StateConfiguration
Ignore the specified trigger when in the configured state, if the guards return true.
func (*StateConfiguration) InitialTransition ¶
func (sc *StateConfiguration) InitialTransition(targetState State) *StateConfiguration
InitialTransition adds internal transition to this state. When entering the current state the state machine will look for an initial transition, and enter the target state.
func (*StateConfiguration) InternalTransition ¶
func (sc *StateConfiguration) InternalTransition(trigger Trigger, action ActionFunc, guards ...GuardFunc) *StateConfiguration
InternalTransition add an internal transition to the state machine. An internal action does not cause the Exit and Entry actions to be triggered, and does not change the state of the state machine.
func (*StateConfiguration) Machine ¶
func (sc *StateConfiguration) Machine() *StateMachine
Machine that is configured with this configuration.
func (*StateConfiguration) OnActive ¶
func (sc *StateConfiguration) OnActive(action func(context.Context) error) *StateConfiguration
OnActive specify an action that will execute when activating the configured state.
func (*StateConfiguration) OnDeactivate ¶
func (sc *StateConfiguration) OnDeactivate(action func(context.Context) error) *StateConfiguration
OnDeactivate specify an action that will execute when deactivating the configured state.
func (*StateConfiguration) OnEntry ¶
func (sc *StateConfiguration) OnEntry(action ActionFunc) *StateConfiguration
OnEntry specify an action that will execute when transitioning into the configured state.
func (*StateConfiguration) OnEntryFrom ¶
func (sc *StateConfiguration) OnEntryFrom(trigger Trigger, action ActionFunc) *StateConfiguration
OnEntryFrom Specify an action that will execute when transitioning into the configured state from a specific trigger.
func (*StateConfiguration) OnExit ¶
func (sc *StateConfiguration) OnExit(action ActionFunc) *StateConfiguration
OnExit specify an action that will execute when transitioning from the configured state.
func (*StateConfiguration) Permit ¶
func (sc *StateConfiguration) Permit(trigger Trigger, destinationState State, guards ...GuardFunc) *StateConfiguration
Permit accept the specified trigger and transition to the destination state if the guard conditions are met (if any).
func (*StateConfiguration) PermitDynamic ¶
func (sc *StateConfiguration) PermitDynamic(trigger Trigger, selector DestinationSelectorFunc, guards ...GuardFunc) *StateConfiguration
PermitDynamic accept the specified trigger and transition to the destination state, calculated dynamically by the supplied function.
func (*StateConfiguration) PermitReentry ¶
func (sc *StateConfiguration) PermitReentry(trigger Trigger, guards ...GuardFunc) *StateConfiguration
PermitReentry accept the specified trigger, execute exit actions and re-execute entry actions. Reentry behaves as though the configured state transitions to an identical sibling state. Applies to the current state only. Will not re-execute superstate actions, or cause actions to execute transitioning between super- and sub-states.
func (*StateConfiguration) State ¶
func (sc *StateConfiguration) State() State
State is configured with this configuration.
func (*StateConfiguration) SubstateOf ¶
func (sc *StateConfiguration) SubstateOf(superstate State) *StateConfiguration
SubstateOf sets the superstate that the configured state is a substate of. Substates inherit the allowed transitions of their superstate. When entering directly into a substate from outside of the superstate, entry actions for the superstate are executed. Likewise when leaving from the substate to outside the supserstate, exit actions for the superstate will execute.
type StateMachine ¶
type StateMachine struct {
// contains filtered or unexported fields
}
A StateMachine is an abstract machine that can be in exactly one of a finite number of states at any given time. It is safe to use the StateMachine concurrently, but non of the callbacks (state manipulation, actions, events, ...) are guarded, so it is up to the client to protect them against race conditions.
func NewStateMachine ¶
func NewStateMachine(initialState State) *StateMachine
NewStateMachine returns a queued state machine.
func NewStateMachineWithExternalStorage ¶
func NewStateMachineWithExternalStorage(stateAccessor func(context.Context) (State, error), stateMutator func(context.Context, State) error, firingMode FiringMode) *StateMachine
NewStateMachineWithExternalStorage returns a state machine with external state storage.
func NewStateMachineWithMode ¶
func NewStateMachineWithMode(initialState State, firingMode FiringMode) *StateMachine
NewStateMachineWithMode returns a state machine with the desired firing mode
func (*StateMachine) ActivateCtx ¶
func (sm *StateMachine) ActivateCtx(ctx context.Context) error
ActivateCtx activates current state. Actions associated with activating the current state will be invoked. The activation is idempotent and subsequent activation of the same current state will not lead to re-execution of activation callbacks.
func (*StateMachine) CanFire ¶
func (sm *StateMachine) CanFire(trigger Trigger, args ...interface{}) (bool, error)
CanFire see CanFireCtx.
func (*StateMachine) CanFireCtx ¶
func (sm *StateMachine) CanFireCtx(ctx context.Context, trigger Trigger, args ...interface{}) (bool, error)
CanFireCtx returns true if the trigger can be fired in the current state.
func (*StateMachine) Configure ¶
func (sm *StateMachine) Configure(state State) *StateConfiguration
Configure begin configuration of the entry/exit actions and allowed transitions when the state machine is in a particular state.
func (*StateMachine) Deactivate ¶
func (sm *StateMachine) Deactivate() error
Deactivate see DeactivateCtx.
func (*StateMachine) DeactivateCtx ¶
func (sm *StateMachine) DeactivateCtx(ctx context.Context) error
DeactivateCtx deactivates current state. Actions associated with deactivating the current state will be invoked. The deactivation is idempotent and subsequent deactivation of the same current state will not lead to re-execution of deactivation callbacks.
func (*StateMachine) Fire ¶
func (sm *StateMachine) Fire(trigger Trigger, args ...interface{}) error
Fire see FireCtx
func (*StateMachine) FireCtx ¶
func (sm *StateMachine) FireCtx(ctx context.Context, trigger Trigger, args ...interface{}) error
FireCtx transition from the current state via the specified trigger. The target state is determined by the configuration of the current state. Actions associated with leaving the current state and entering the new one will be invoked.
An error is returned if any of the state machine actions or the state callbacks return an error without wrapping. It can also return an error if the trigger is not mapped to any state change, being this error the one returned by `OnUnhandledTrigger` func.
There is no rollback mechanism in case there is an action error after the state has been changed. Guard clauses or error states can be used gracefully handle this situations.
The context is passed down to all actions and callbacks called within the scope of this method. There is no context error checking, although it may be implemented in future releases.
func (*StateMachine) Firing ¶ added in v1.5.4
func (sm *StateMachine) Firing() bool
Firing returns true when the state machine is processing a trigger.
func (*StateMachine) IsInState ¶
func (sm *StateMachine) IsInState(state State) (bool, error)
IsInState see IsInStateCtx.
func (*StateMachine) IsInStateCtx ¶
IsInStateCtx determine if the state machine is in the supplied state. Returns true if the current state is equal to, or a substate of, the supplied state.
func (*StateMachine) MustState ¶
func (sm *StateMachine) MustState() State
MustState returns the current state without the error. It is safe to use this method when used together with NewStateMachine or when using NewStateMachineWithExternalStorage with an state accessor that does not return an error.
func (*StateMachine) OnTransitioned ¶
func (sm *StateMachine) OnTransitioned(fn ...TransitionFunc)
OnTransitioned registers a callback that will be invoked every time the state machine successfully finishes a transitions from one state into another.
func (*StateMachine) OnTransitioning ¶ added in v1.5.4
func (sm *StateMachine) OnTransitioning(fn ...TransitionFunc)
OnTransitioning registers a callback that will be invoked every time the state machine starts a transitions from one state into another.
func (*StateMachine) OnUnhandledTrigger ¶
func (sm *StateMachine) OnUnhandledTrigger(fn UnhandledTriggerActionFunc)
OnUnhandledTrigger override the default behaviour of returning an error when an unhandled trigger.
func (*StateMachine) PermittedTriggers ¶
func (sm *StateMachine) PermittedTriggers(args ...interface{}) ([]Trigger, error)
PermittedTriggers see PermittedTriggersCtx.
func (*StateMachine) PermittedTriggersCtx ¶
func (sm *StateMachine) PermittedTriggersCtx(ctx context.Context, args ...interface{}) ([]Trigger, error)
PermittedTriggersCtx returns the currently-permissible trigger values.
func (*StateMachine) PossibleTriggers ¶
func (sm *StateMachine) PossibleTriggers(args ...interface{}) ([]PossibleTrigger, error)
PermittedTriggers see PermittedTriggersCtx.
func (*StateMachine) PossibleTriggersCtx ¶
func (sm *StateMachine) PossibleTriggersCtx(ctx context.Context, args ...interface{}) ([]PossibleTrigger, error)
PermittedTriggersCtx returns the currently-permissible trigger values.
func (*StateMachine) SetTriggerParameters ¶
func (sm *StateMachine) SetTriggerParameters(trigger Trigger, argumentTypes ...reflect.Type)
SetTriggerParameters specify the arguments that must be supplied when a specific trigger is fired.
func (*StateMachine) State ¶
func (sm *StateMachine) State(ctx context.Context) (State, error)
State returns the current state.
func (*StateMachine) String ¶
func (sm *StateMachine) String() string
String returns a human-readable representation of the state machine. It is not guaranteed that the order of the PermittedTriggers is the same in consecutive executions.
func (*StateMachine) ToGraph ¶
func (sm *StateMachine) ToGraph() string
ToGraph returns the DOT representation of the state machine. It is not guaranteed that the returned string will be the same in different executions.
type Transition ¶
type Transition struct { Source State Destination State Trigger Trigger // contains filtered or unexported fields }
Transition describes a state transition.
func GetTransition ¶
func GetTransition(ctx context.Context) Transition
GetTransition returns the transition from the context. If there is no transition the returned value is empty.
func (*Transition) IsReentry ¶
func (t *Transition) IsReentry() bool
IsReentry returns true if the transition is a re-entry, i.e. the identity transition.
type TransitionFunc ¶ added in v1.5.4
type TransitionFunc = func(context.Context, Transition)