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.Fire(triggerCallDialed, "qmuntal") 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 %s\n", phoneCall.MustState()) phoneCall.ToGraph() } 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 : [qmuntal] [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 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, ...) *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) (bool, error)
- func (sm *StateMachine) CanFireCtx(ctx context.Context, trigger Trigger) (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) 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(onTransitionAction func(context.Context, Transition))
- func (sm *StateMachine) OnUnhandledTrigger(onUnhandledTriggerAction 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{}) ([]Trigger, error)
- func (sm *StateMachine) PossibleTriggersCtx(ctx context.Context, args ...interface{}) ([]Trigger, 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 Trigger
- type TriggerWithParameters
- 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 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, destinationSelector func(context.Context, ...interface{}) (State, error), 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. Reading and writing to the state store is protected by mutual exclusion locks, therefore it is safe to use the StateMachine concurrently. All the other actions (OnEntry, OnActivate, ...) are not thread-safe and is up to the client to decide if it is necessary to protected them.
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 currrent 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) (bool, error)
CanFire see CanFireCtx.
func (*StateMachine) CanFireCtx ¶
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 currrent 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.
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(onTransitionAction func(context.Context, Transition))
OnTransitioned registers a callback that will be invoked every time the statemachine transitions from one state into another.
func (*StateMachine) OnUnhandledTrigger ¶
func (sm *StateMachine) OnUnhandledTrigger(onUnhandledTriggerAction 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{}) ([]Trigger, error)
PermittedTriggers see PermittedTriggersCtx.
func (*StateMachine) PossibleTriggersCtx ¶
func (sm *StateMachine) PossibleTriggersCtx(ctx context.Context, args ...interface{}) ([]Trigger, 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 ¶
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 Trigger ¶
type Trigger = interface{}
Trigger is used to represent the triggers that cause state transitions.
type TriggerWithParameters ¶
TriggerWithParameters associates configured parameters with an underlying trigger value.