Documentation
¶
Overview ¶
Package machine is a general purpose state machine for managing complex async workflows in a safe and structured way.
It's a dependency-free implementation of AsyncMachine in Golang using channels and context. It aims at simplicity and speed.
Index ¶
- Constants
- Variables
- func IsActiveTick(tick uint64) bool
- func IsTimeAfter(time1, time2 T) bool
- func NewArgsMapper(names []string, maxlen int) func(args A) map[string]string
- func NormalizeID(id string) string
- type A
- type Clocks
- type DefaultRelationsResolver
- func (rr *DefaultRelationsResolver) GetAutoMutation() *Mutation
- func (rr *DefaultRelationsResolver) GetRelationsBetween(fromState, toState string) ([]Relation, error)
- func (rr *DefaultRelationsResolver) GetRelationsOf(fromState string) ([]Relation, error)
- func (rr *DefaultRelationsResolver) GetTargetStates(t *Transition, calledStates S) S
- func (rr *DefaultRelationsResolver) SortStates(states S)
- type Event
- type ExceptionArgsPanic
- type ExceptionHandler
- type LogEntry
- type LogLevel
- type Logger
- type Machine
- func (m *Machine) ActiveStates() S
- func (m *Machine) Add(states S, args A) Result
- func (m *Machine) Add1(state string, args A) Result
- func (m *Machine) AddErr(err error) Result
- func (m *Machine) AddErrStr(err string) Result
- func (m *Machine) AddFromEv(states S, event *Event, args A) Result
- func (m *Machine) Any(states ...S) bool
- func (m *Machine) Any1(states ...string) bool
- func (m *Machine) BindHandlers(handlers any) error
- func (m *Machine) CanAdd(states S) bool
- func (m *Machine) CanRemove(states S) bool
- func (m *Machine) CanSet(states S) bool
- func (m *Machine) Clock(state string) uint64
- func (m *Machine) Clocks(states S) Clocks
- func (m *Machine) Dispose()
- func (m *Machine) DisposeForce()
- func (m *Machine) DuringTransition() bool
- func (m *Machine) Eval(source string, fn func(), ctx context.Context) bool
- func (m *Machine) GetLogArgs() func(args A) map[string]string
- func (m *Machine) GetLogLevel() LogLevel
- func (m *Machine) GetLogger() Logger
- func (m *Machine) GetStruct() Struct
- func (m *Machine) Has(states S) bool
- func (m *Machine) Has1(state string) bool
- func (m *Machine) HasStateChanged(before S) bool
- func (m *Machine) HasStateChangedSince(clocks Clocks) bool
- func (m *Machine) Inspect(states S) string
- func (m *Machine) Is(states S) bool
- func (m *Machine) Is1(state string) bool
- func (m *Machine) IsClock(state string, tick uint64) bool
- func (m *Machine) IsErr() bool
- func (m *Machine) IsQueued(mutationType MutationType, states S, withoutArgsOnly bool, ...) int
- func (m *Machine) Log(msg string, args ...any)
- func (m *Machine) MustParseStates(states S) S
- func (m *Machine) NewStateCtx(state string) context.Context
- func (m *Machine) Not(states S) bool
- func (m *Machine) Not1(state string) bool
- func (m *Machine) OnEvent(events []string, ctx context.Context) chan *Event
- func (m *Machine) Queue() []*Mutation
- func (m *Machine) RegisterDisposalHandler(fn func())
- func (m *Machine) Remove(states S, args A) Result
- func (m *Machine) Remove1(state string, args A) Result
- func (m *Machine) RemoveFromEv(states S, event *Event, args A) Result
- func (m *Machine) Set(states S, args A) Result
- func (m *Machine) SetFromEv(states S, event *Event, args A) Result
- func (m *Machine) SetLogArgs(matcher func(args A) map[string]string)
- func (m *Machine) SetLogLevel(level LogLevel)
- func (m *Machine) SetLogger(fn Logger)
- func (m *Machine) SetStruct(statesStruct Struct, names S) error
- func (m *Machine) SetTestLogger(logf func(format string, args ...any), level LogLevel)
- func (m *Machine) String() string
- func (m *Machine) StringAll() string
- func (m *Machine) Switch(states ...string) string
- func (m *Machine) Time(states S) T
- func (m *Machine) TimeSum(states S) uint64
- func (m *Machine) VerifyStates(states S) error
- func (m *Machine) When(states S, ctx context.Context) <-chan struct{}
- func (m *Machine) When1(state string, ctx context.Context) <-chan struct{}
- func (m *Machine) WhenArgs(state string, args A, ctx context.Context) <-chan struct{}
- func (m *Machine) WhenDisposed() <-chan struct{}
- func (m *Machine) WhenErr(ctx context.Context) <-chan struct{}
- func (m *Machine) WhenNot(states S, ctx context.Context) <-chan struct{}
- func (m *Machine) WhenNot1(state string, ctx context.Context) <-chan struct{}
- func (m *Machine) WhenQueueEnds(ctx context.Context) <-chan struct{}
- func (m *Machine) WhenTicks(state string, ticks int, ctx context.Context) <-chan struct{}
- func (m *Machine) WhenTicksEq(state string, ticks int, ctx context.Context) <-chan struct{}
- func (m *Machine) WhenTime(states S, times T, ctx context.Context) <-chan struct{}
- type Mutation
- type MutationType
- type NoOpTracer
- func (t *NoOpTracer) End()
- func (t *NoOpTracer) HandlerEnd(transition *Transition, emitter string, handler string)
- func (t *NoOpTracer) HandlerStart(transition *Transition, emitter string, handler string)
- func (t *NoOpTracer) Inheritable() bool
- func (t *NoOpTracer) MachineDispose(machID string)
- func (t *NoOpTracer) MachineInit(mach *Machine)
- func (t *NoOpTracer) NewSubmachine(parent, mach *Machine)
- func (t *NoOpTracer) QueueEnd(machine *Machine)
- func (t *NoOpTracer) TransitionEnd(transition *Transition)
- func (t *NoOpTracer) TransitionInit(transition *Transition)
- type Opts
- type Relation
- type RelationsResolver
- type Result
- type S
- type State
- type Step
- type StepType
- type Struct
- type T
- type Tracer
- type Transition
Examples ¶
Constants ¶
const ( // EventTransitionEnd transition ended EventTransitionEnd = "transition-end" // EventTransitionInit transition being initialized EventTransitionInit = "transition-init" // EventTransitionStart transition started EventTransitionStart = "transition-start" // EventTransitionCancel transition canceled EventTransitionCancel = "transition-cancel" // EventQueueEnd queue fully drained EventQueueEnd = "queue-end" // EventQueueAdd new mutation queued EventQueueAdd = "queue-add" // EventStructChange machine's states structure have changed EventStructChange = "struct-change" // EventTick active states changed, at least one state clock increased EventTick = "tick" // EventException Exception state becomes active EventException = "exception" )
const ( // Exception is a name the Exception state. Exception = "Exception" // Any is a name of a meta state used in catch-all handlers. Any = "Any" )
Variables ¶
var ( // ErrStateUnknown indicates that the state is unknown. ErrStateUnknown = errors.New("state unknown") // ErrCanceled can be used to indicate a canceled Transition. Not used ATM. ErrCanceled = errors.New("transition canceled") // ErrQueued can be used to indicate a queued Transition. Not used ATM. ErrQueued = errors.New("transition queued") // ErrInvalidArgs can be used to indicate invalid arguments. Not used ATM. ErrInvalidArgs = errors.New("invalid arguments") // ErrTimeout can be used to indicate timed out mutation. Not used ATM. ErrTimeout = errors.New("timeout") )
Functions ¶
func IsActiveTick ¶ added in v0.5.0
IsActiveTick returns true if the tick represents an active state (odd number).
func IsTimeAfter ¶
IsTimeAfter checks if time1 is after time2. Requires a deterministic states order, e.g. by using Machine.VerifyStates.
func NewArgsMapper ¶ added in v0.5.0
NewArgsMapper returns a matcher function for LogArgs. Useful for debugging untyped argument maps.
maxlen: maximum length of the string representation of the argument (default=20).
func NormalizeID ¶ added in v0.5.0
Types ¶
type DefaultRelationsResolver ¶
type DefaultRelationsResolver struct { Machine *Machine Transition *Transition }
DefaultRelationsResolver is the default implementation of the RelationsResolver with Add, Remove, Require and After. It can be overridden using Opts.Resolver.
func (*DefaultRelationsResolver) GetAutoMutation ¶
func (rr *DefaultRelationsResolver) GetAutoMutation() *Mutation
GetAutoMutation implements RelationsResolver.GetAutoMutation.
func (*DefaultRelationsResolver) GetRelationsBetween ¶ added in v0.5.0
func (rr *DefaultRelationsResolver) GetRelationsBetween( fromState, toState string, ) ([]Relation, error)
GetRelationsBetween returns a list of directional relation types between the given states. Not thread safe.
func (*DefaultRelationsResolver) GetRelationsOf ¶ added in v0.5.0
func (rr *DefaultRelationsResolver) GetRelationsOf(fromState string) ( []Relation, error, )
GetRelationsOf returns a list of relation types of the given state. Not thread safe.
func (*DefaultRelationsResolver) GetTargetStates ¶
func (rr *DefaultRelationsResolver) GetTargetStates( t *Transition, calledStates S, ) S
GetTargetStates implements RelationsResolver.GetTargetStates.
func (*DefaultRelationsResolver) SortStates ¶
func (rr *DefaultRelationsResolver) SortStates(states S)
SortStates implements RelationsResolver.SortStates.
type Event ¶
type Event struct { // Name of the event / handler Name string // Machine is the machine that the event belongs to, it can be used to access // the current Transition and Mutation. Machine *Machine // Args is a map of named arguments for a Mutation. Args A // contains filtered or unexported fields }
Event struct represents a single event of a Mutation withing a Transition. One event can have 0-n handlers.
func (*Event) Transition ¶ added in v0.5.0
func (e *Event) Transition() *Transition
Transition returns the Transition of an Event.
type ExceptionArgsPanic ¶
type ExceptionArgsPanic struct { CalledStates S StatesBefore S Transition *Transition LastStep *Step StackTrace []byte }
ExceptionArgsPanic is an optional argument ["panic"] for the Exception state which describes a panic within a Transition handler.
type ExceptionHandler ¶
type ExceptionHandler struct{}
ExceptionHandler provide a basic Exception state support, as should be embedded into handler structs in most of the cases.
func (*ExceptionHandler) ExceptionState ¶
func (eh *ExceptionHandler) ExceptionState(e *Event)
ExceptionState is a final entry handler for the Exception state. Args: - err error: The error that caused the Exception state. - panic *ExceptionArgsPanic: Optional details about the panic.
type LogLevel ¶
type LogLevel int
LogLevel enum
const ( // LogNothing means no logging, including external msgs. LogNothing LogLevel = iota // LogChanges means logging state changes and external msgs. LogChanges // LogOps means LogChanges + logging all the operations. LogOps // LogDecisions means LogOps + logging all the decisions behind them. LogDecisions // LogEverything means LogDecisions + all event and emitter names, and more. LogEverything )
type Machine ¶
type Machine struct { // Unique ID of this machine. Default: random ID. Read-only. ID string // Time for a handler to execute. Default: time.Second HandlerTimeout time.Duration // If true, the machine will print all exceptions to stdout. Default: true. // Requires an ExceptionHandler binding and Machine.PanicToException set. PrintExceptions bool // If true, the machine will catch panic and trigger the Exception state. // Default: true. PanicToException bool // If true, logs will start with machine's ID (5 chars). // Default: true. LogID bool // Relations resolver, used to produce target states of a transition. // Default: *DefaultRelationsResolver. Read-only. Resolver RelationsResolver // Ctx is the context of the machine. Read-only. Ctx context.Context // Err is the last error that occurred. Read-only. Err error // Maximum number of mutations that can be queued. Default: 1000. QueueLimit int // Currently executing transition (if any). Read-only. Transition *Transition // List of all the registered state names. Read-only. StateNames S // Confirms the states have been ordered using VerifyStates. Read-only. StatesVerified bool // Tracers are optional tracers for telemetry integrations. Tracers []Tracer // If true, the machine has been Disposed and is no-op. Read-only. Disposed bool // ParentID is the ID of the parent machine (if any). ParentID string // Tags are optional tags for telemetry integrations etc. Tags []string // contains filtered or unexported fields }
Machine represent states, provides mutation methods, helpers methods and info about the current and scheduled transitions (if any).
func New ¶
New creates a new Machine instance, bound to context and modified with optional Opts.
Example ¶
t := &testing.T{} // Replace this with actual *testing.T in real test cases initialState := S{"A"} mach := NewNoRels(t, initialState) // machine mach ready _ = mach
Output:
func NewCommon ¶ added in v0.5.0
func NewCommon( ctx context.Context, id string, statesStruct Struct, stateNames S, handlers any, parent *Machine, opts *Opts, ) (*Machine, error)
NewCommon creates a new Machine instance with all the common options set.
Example ¶
t := &testing.T{} // Replace this with actual *testing.T in real test cases initialState := S{"A"} mach := NewNoRels(t, initialState) // machine mach ready _ = mach
Output:
func (*Machine) ActiveStates ¶
ActiveStates returns a copy of the currently active states.
func (*Machine) Add ¶
Add activates a list of states in the machine, returning the result of the transition (Executed, Queued, Canceled). Like every mutation method, it will resolve relations and trigger handlers.
func (*Machine) Add1 ¶ added in v0.5.0
Add1 is a shorthand method to add a single state with the passed args.
func (*Machine) AddErr ¶
AddErr is a shorthand method to add the Exception state with the passed error. Like every mutation method, it will resolve relations and trigger handlers.
func (*Machine) AddErrStr ¶
AddErrStr is a shorthand method to add the Exception state with the passed error string. Like every mutation method, it will resolve relations and trigger handlers.
func (*Machine) Any ¶
Any is group call to Is, returns true if any of the params return true from Is.
machine.StringAll() // ()[Foo:0 Bar:0 Baz:0] machine.Add(S{"Foo"}) // is(Foo, Bar) or is(Bar) machine.Any(S{"Foo", "Bar"}, S{"Bar"}) // false // is(Foo) or is(Bar) machine.Any(S{"Foo"}, S{"Bar"}) // true
func (*Machine) Any1 ¶ added in v0.5.0
Any1 is group call to Is1(), returns true if any of the params return true from Is1().
func (*Machine) BindHandlers ¶
BindHandlers binds a struct of handler methods to the machine's states. Returns a HandlerBinding object, which signals when the binding is ready. TODO verify method signatures early TODO detect handlers for unknown states
func (*Machine) Clocks ¶ added in v0.5.0
Clocks returns the map of specified clocks or all clocks if states is nil.
func (*Machine) Dispose ¶
func (m *Machine) Dispose()
Dispose disposes the machine and all its emitters. You can wait for the completion of the disposal with `<-mach.WhenDisposed`.
func (*Machine) DisposeForce ¶ added in v0.5.0
func (m *Machine) DisposeForce()
DisposeForce disposes the machine and all its emitters, without waiting for the queue to drain. Will cause panics.
func (*Machine) DuringTransition ¶
DuringTransition checks if the machine is currently during a transition.
func (*Machine) Eval ¶ added in v0.5.0
Eval executes a function on the machine's queue, allowing to avoid using locks for non-handler code. Blocking code should NOT be scheduled here. Eval cannot be called within a handler's critical section, as both are using the same serial queue and will deadlock. Eval has a timeout of HandlerTimeout/2 and will return false in case it happens.
ctx: nil context defaults to machine's context.
Note: usage of Eval is discouraged.
func (*Machine) GetLogArgs ¶ added in v0.5.0
GetLogArgs returns the current log args function.
func (*Machine) GetLogLevel ¶ added in v0.3.0
GetLogLevel returns the log level of the machine.
func (*Machine) GetLogger ¶ added in v0.3.0
GetLogger returns the current custom logger function, or nil.
func (*Machine) Has1 ¶ added in v0.5.0
Has1 is a shorthand for Has. It returns true if the passed state is registered in the machine.
func (*Machine) HasStateChanged ¶
HasStateChanged checks current active states have changed from the passed ones.
func (*Machine) HasStateChangedSince ¶ added in v0.5.0
HasStateChangedSince checks if the machine has changed since the passed clocks. Returns true if at least one state has changed.
func (*Machine) Inspect ¶
Inspect returns a multi-line string representation of the machine (states, relations, clocks). states: param for ordered or partial results.
func (*Machine) Is ¶
Is checks if all the passed states are currently active.
machine.StringAll() // ()[Foo:0 Bar:0 Baz:0] machine.Add(S{"Foo"}) machine.Is(S{"Foo"}) // true machine.Is(S{"Foo", "Bar"}) // false
func (*Machine) Is1 ¶ added in v0.5.0
Is1 is a shorthand method to check if a single state is currently active. See Is().
func (*Machine) IsClock ¶
IsClock checks if the passed state's clock equals the passed tick.
tick := m.Clock("A") m.Remove("A") m.Add("A") m.Is("A", tick) // -> false
func (*Machine) IsQueued ¶
func (m *Machine) IsQueued(mutationType MutationType, states S, withoutArgsOnly bool, statesStrictEqual bool, startIndex int, ) int
IsQueued checks if a particular mutation has been queued. Returns an index of the match or -1 if not found.
mutationType: add, remove, set
states: list of states used in the mutation
withoutParamsOnly: matches only mutation without the arguments object
statesStrictEqual: states of the mutation have to be exactly like `states` and not a superset. TODO test
func (*Machine) Log ¶
Log logs an [extern] message unless LogNothing is set (default). Optionally redirects to a custom logger from SetLogger.
func (*Machine) MustParseStates ¶
MustParseStates parses the states and returns them as a list. Panics when a state is not defined. It's an usafe equivalent of VerifyStates.
func (*Machine) NewStateCtx ¶ added in v0.5.0
NewStateCtx returns a new sub-context, bound to the current clock's tick of the passed state.
Context cancels when the state has been de-activated, or right away, if it isn't currently active.
State contexts are used to check state expirations and should be checked often inside goroutines. TODO reuse existing ctxs
func (*Machine) Not ¶
Not checks if **none** of the passed states are currently active.
machine.StringAll() // -> ()[A:0 B:0 C:0 D:0] machine.Add(S{"A", "B"}) // not(A) and not(C) machine.Not(S{"A", "C"}) // -> false // not(C) and not(D) machine.Not(S{"C", "D"}) // -> true
func (*Machine) Not1 ¶ added in v0.5.0
Not1 is a shorthand method to check if a single state is currently inactive. See Not().
func (*Machine) OnEvent ¶ added in v0.5.0
OnEvent returns a channel that will be notified with *Event, when any of the passed events happen. It's a quick substitute for predefined transition handlers, although it does not support negotiation.
ctx: optional context to dispose the emitter early.
It's not supported to nest OnEvent() calls, as it would cause a deadlock. Using OnEvent is recommended only in special cases, like test assertions. The Tracer API is a better way to event feeds.
func (*Machine) RegisterDisposalHandler ¶ added in v0.5.0
func (m *Machine) RegisterDisposalHandler(fn func())
RegisterDisposalHandler adds a function to be called when the machine is disposed. This function will block before mach.WhenDispose is closed.
func (*Machine) Remove ¶
Remove de-activates a list of states in the machine, returning the result of the transition (Executed, Queued, Canceled). Like every mutation method, it will resolve relations and trigger handlers.
func (*Machine) Remove1 ¶ added in v0.5.0
Remove1 is a shorthand method to remove a single state with the passed args. See Remove().
func (*Machine) RemoveFromEv ¶ added in v0.5.0
RemoveFromEv TODO RemoveFromEv Planned.
func (*Machine) Set ¶
Set de-activates a list of states in the machine, returning the result of the transition (Executed, Queued, Canceled). Like every mutation method, it will resolve relations and trigger handlers.
func (*Machine) SetLogArgs ¶ added in v0.5.0
SetLogArgs accepts a function which decides which mutation arguments to log. See NewArgsMapper or create your own manually.
func (*Machine) SetLogLevel ¶
SetLogLevel sets the log level of the machine.
func (*Machine) SetStruct ¶ added in v0.5.0
SetStruct sets the machine's state structure. It will automatically call VerifyStates with the names param and emit EventStructChange if successful. Note: it's not recommended to change the states structure of a machine which has already produced transitions.
func (*Machine) SetTestLogger ¶ added in v0.5.0
SetTestLogger hooks into the testing.Logf and set the log level in one call. Useful for testing. Requires LogChanges log level to produce any output.
func (*Machine) String ¶
String returns a one line representation of the currently active states, with their clock values. Inactive states are omitted. Eg: (Foo:1 Bar:3)
func (*Machine) StringAll ¶
StringAll returns a one line representation of all the states, with their clock values. Inactive states are in square brackets. Eg: (Foo:1 Bar:3)[Baz:2]
func (*Machine) Switch ¶ added in v0.3.0
Switch returns the first state from the passed list that is currently active, making it useful for switch statements.
switch mach.Switch(ss.GroupPlaying...) { case "Playing": case "Paused": case "Stopped": }
func (*Machine) Time ¶
Time returns a list of logical clocks of specified states (or all the states if nil). states: optionally passing a list of states param guarantees a deterministic order of the result.
func (*Machine) TimeSum ¶
TimeSum returns the sum of logical clocks of specified states (or all states if nil). It's a very inaccurate, yet simple way to measure the machine's time. TODO handle overflow
func (*Machine) VerifyStates ¶ added in v0.3.0
VerifyStates verifies an array of state names and returns an error in case at least one isn't defined. It also retains the order and uses it for StateNames (only if all states have been passed). Not thread-safe.
func (*Machine) When ¶
When returns a channel that will be closed when all the passed states become active or the machine gets disposed.
ctx: optional context that will close the channel when done. Useful when listening on 2 When() channels within the same `select` to GC the 2nd one. TODO re-use channels with the same state set and context
func (*Machine) WhenArgs ¶ added in v0.5.0
WhenArgs returns a channel that will be closed when the passed state becomes active with all the passed args. Args are compared using the native '=='. It's meant to be used with async Multi states, to filter out a specific completion. TODO better val comparisons
func (*Machine) WhenDisposed ¶ added in v0.5.0
func (m *Machine) WhenDisposed() <-chan struct{}
func (*Machine) WhenErr ¶
WhenErr returns a channel that will be closed when the machine is in the Exception state.
ctx: optional context defaults to the machine's context.
func (*Machine) WhenNot ¶
WhenNot returns a channel that will be closed when all the passed states become inactive or the machine gets disposed.
ctx: optional context that will close the channel when done. Useful when listening on 2 WhenNot() channels within the same `select` to GC the 2nd one.
func (*Machine) WhenNot1 ¶ added in v0.5.0
WhenNot1 is an alias to WhenNot() for a single state. See WhenNot.
func (*Machine) WhenQueueEnds ¶ added in v0.5.0
WhenQueueEnds closes every time the queue ends, or the optional ctx expires.
func (*Machine) WhenTicks ¶ added in v0.5.0
WhenTicks waits N tick for a single state. Uses WhenTime underneath.
func (*Machine) WhenTicksEq ¶ added in v0.5.0
WhenTicksEq waits till ticks for a single state equal the given value. Uses WhenTime underneath.
type Mutation ¶
type Mutation struct { // add, set, remove Type MutationType // states explicitly passed to the mutation method CalledStates S // argument map passed to the mutation method (if any). Args A // this mutation has been triggered by an auto state Auto bool // specific context for this mutation (optional) Ctx context.Context // optional eval func, only for MutationEval Eval func() }
Mutation represents an atomic change (or an attempt) of machine's active states. Mutation causes a Transition.
func (Mutation) StateWasCalled ¶ added in v0.5.0
StateWasCalled returns true if the Mutation was called (directly) with the passed state (in opposite to it coming from an `Add` relation). TODO change to CalledIs(), CalledIs1(), CalledAny(), CalledAny1()
type MutationType ¶
type MutationType int
MutationType enum
const ( MutationAdd MutationType = iota MutationRemove MutationSet MutationEval )
func (MutationType) String ¶
func (m MutationType) String() string
type NoOpTracer ¶ added in v0.6.0
type NoOpTracer struct{}
NoOpTracer is a no-op implementation of Tracer, used for embedding.
func (*NoOpTracer) End ¶ added in v0.6.0
func (t *NoOpTracer) End()
func (*NoOpTracer) HandlerEnd ¶ added in v0.6.0
func (t *NoOpTracer) HandlerEnd( transition *Transition, emitter string, handler string)
func (*NoOpTracer) HandlerStart ¶ added in v0.6.0
func (t *NoOpTracer) HandlerStart( transition *Transition, emitter string, handler string)
func (*NoOpTracer) Inheritable ¶ added in v0.6.0
func (t *NoOpTracer) Inheritable() bool
func (*NoOpTracer) MachineDispose ¶ added in v0.6.0
func (t *NoOpTracer) MachineDispose(machID string)
func (*NoOpTracer) MachineInit ¶ added in v0.6.0
func (t *NoOpTracer) MachineInit(mach *Machine)
func (*NoOpTracer) NewSubmachine ¶ added in v0.6.0
func (t *NoOpTracer) NewSubmachine(parent, mach *Machine)
func (*NoOpTracer) QueueEnd ¶ added in v0.6.0
func (t *NoOpTracer) QueueEnd(machine *Machine)
func (*NoOpTracer) TransitionEnd ¶ added in v0.6.0
func (t *NoOpTracer) TransitionEnd(transition *Transition)
func (*NoOpTracer) TransitionInit ¶ added in v0.6.0
func (t *NoOpTracer) TransitionInit(transition *Transition)
type Opts ¶
type Opts struct { // Unique ID of this machine. Default: random ID. ID string // Time for a handler to execute. Default: time.Second HandlerTimeout time.Duration // If true, the machine will NOT print all exceptions to stdout. DontPrintExceptions bool // If true, the machine will die on panics. DontPanicToException bool // If true, the machine will NOT prefix its logs with its ID. DontLogID bool // Custom relations resolver. Default: *DefaultRelationsResolver. Resolver RelationsResolver // Log level of the machine. Default: LogNothing. LogLevel LogLevel // Tracer for the machine. Default: nil. Tracers []Tracer // LogArgs matching function for the machine. Default: nil. LogArgs func(args A) map[string]string // Parent machine, used to inherit certain properties, e.g. tracers. // Overrides ParentID. Default: nil. Parent *Machine // ParentID is the ID of the parent machine. Default: "". ParentID string // Tags is a list of tags for the machine. Default: nil. Tags []string // QueueLimit is the maximum number of mutations that can be queued. // Default: 1000. // TODO per-state QueueLimit QueueLimit int }
Opts struct is used to configure a new Machine.
func OptsWithDebug ¶ added in v0.5.0
OptsWithDebug returns Opts with debug settings (DontPanicToException, long HandlerTimeout).
func OptsWithParentTracers ¶ added in v0.5.0
OptsWithParentTracers returns Opts with the parent's Opts.Tracers and Opts.LogArgs.
func OptsWithTracers ¶ added in v0.5.0
OptsWithTracers returns Opts with the given tracers. Tracers are inherited by submachines (via Opts.Parent) when env.AM_DEBUG is set.
type RelationsResolver ¶
type RelationsResolver interface { // GetTargetStates returns the target states after parsing the relations. GetTargetStates(t *Transition, calledStates S) S // GetAutoMutation returns an (optional) auto mutation which is appended to // the queue after the transition is executed. GetAutoMutation() *Mutation // SortStates sorts the states in the order their handlers should be // executed. SortStates(states S) // GetRelationsOf returns a list of relation types of the given state. GetRelationsOf(fromState string) ([]Relation, error) // GetRelationsBetween returns a list of relation types between the given // states. GetRelationsBetween(fromState, toState string) ([]Relation, error) }
RelationsResolver is an interface for parsing relations between states. Not thread-safe. TODO support custom relation types and additional state properties.
type Result ¶
type Result int
Result enum is the result of a state Transition
const ( // Executed means that the transition was executed immediately and not // canceled. Executed Result = 1 << iota // Canceled means that the transition was canceled, by either relations or a // handler. Canceled // Queued means that the transition was queued for later execution. The // following methods can be used to wait for the results: // - Machine.When // - Machine.WhenNot // - Machine.WhenArgs // - Machine.WhenTime Queued )
type S ¶
type S []string
S (state names) is a string list of state names.
func DiffStates ¶
DiffStates returns the states that are in states1 but not in states2.
type Step ¶ added in v0.5.0
type Step struct { Type StepType // optional, unless no ToState FromState string // optional, unless no FromState ToState string // eg a transition method name, relation type Data any // marks a final handler (FooState, FooEnd) IsFinal bool // marks a self handler (FooFoo) IsSelf bool // marks an enter handler (FooEnter). Requires IsFinal. IsEnter bool }
Step struct represents a single step within a Transition, either a relation resolving step or a handler call.
type Struct ¶ added in v0.5.0
Struct is a map of state names to state definitions.
func CloneStates ¶ added in v0.5.0
CloneStates deep clones the states struct and returns a copy.
type Tracer ¶ added in v0.5.0
type Tracer interface { TransitionInit(transition *Transition) TransitionEnd(transition *Transition) HandlerStart(transition *Transition, emitter string, handler string) HandlerEnd(transition *Transition, emitter string, handler string) End() MachineInit(machine *Machine) MachineDispose(machID string) NewSubmachine(parent, machine *Machine) Inheritable() bool // TODO NewStatesStruct // TODO VerifyStates QueueEnd(machine *Machine) }
Tracer is an interface for logging machine transitions and events, used by Opts.Tracers.
type Transition ¶
type Transition struct { ID string // List of steps taken by this transition (so far). Steps []*Step // When true, execution of the transition has been completed. IsCompleted bool // states before the transition StatesBefore S // clocks of the states from before the transition // TODO timeBefore, produce Clocks via ClockBefore(), add index diffs ClocksBefore Clocks // clocks of the states from after the transition // TODO timeAfter, produce Clocks via ClockAfter(), add index diffs // TODO unify with pkg/telemetry ClocksAfter Clocks TAfter T // Struct with "enter" handlers to execute Enters S // Struct with "exit" handlers to executed Exits S // target states after parsing the relations TargetStates S // was the transition accepted (during the negotiation phase) Accepted bool // Mutation call which caused this transition Mutation *Mutation // Parent machine Machine *Machine // Log entries produced during the transition LogEntries []*LogEntry // contains filtered or unexported fields }
Transition represents processing of a single mutation within a machine.
func (*Transition) Args ¶
func (t *Transition) Args() A
Args returns the argument map passed to the mutation method (or an empty one).
func (*Transition) CalledStates ¶
func (t *Transition) CalledStates() S
CalledStates return explicitly called / requested states of the transition.
func (*Transition) IsAuto ¶
func (t *Transition) IsAuto() bool
IsAuto returns true if the transition was triggered by an auto state. Thus, it cant trigger any other auto state mutations.
func (*Transition) LogArgs ¶ added in v0.5.0
func (t *Transition) LogArgs() string
LogArgs returns a text snippet with arguments which should be logged for this Mutation.
func (*Transition) String ¶
func (t *Transition) String() string
String representation of the transition and the steps taken so far. TODO: implement, test
func (*Transition) Type ¶
func (t *Transition) Type() MutationType
Type returns the type of the mutation (add, remove, set).