sm

package
v0.0.0-...-3e52749 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 26, 2022 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// TagStartSM identifies the message used to start a state machine
	// goroutine
	TagStartSM = -1

	// TagStopSM identifies the message used to terminate a state machine
	// goroutine
	TagStopSM = -2
)

Variables

View Source
var (
	// NullEnter defines a state entry function that does nothing.
	NullEnter EnterFunc = nil

	// NullLeave defines a state exit function that does nothing.
	NullLeave LeaveFunc = nil

	// Stay is used in an ActionEntry as shorthand to indicate that there is
	// no state transition to process.
	Stay StateIndex = nil
)

Functions

func Ignore

func Ignore(ctx context.Context, machine *SM, msg Envelope) bool

Ignore is a standard processing action that ignores the arriving message, and closes any provided reply channel.

func NullSaver

func NullSaver(ctx context.Context, machine *SM, starting bool) error

NullSaver is a function that provides the 'no-save' (or null) save handler support for state machines that do not save state to an external store.

func TerminalEnter

func TerminalEnter(_ context.Context, machine *SM) error

TerminalEnter is the standard terminal state Enter handler, which marks the state machine as terminated.

func UnexpectedMessage

func UnexpectedMessage(ctx context.Context, machine *SM, msg Envelope) bool

UnexpectedMessage is an action function that signals that the incoming message was not expected, and its presence suggests a model consistency failure.

Types

type ActionEntry

type ActionEntry struct {
	// Match is the message Tag value which causes this rule to trigger.
	Match int

	// Action is the processing function to call.
	Action ActionFunc

	// TrueState is the state ID to change to if Action returns true.
	TrueState StateIndex

	// FalseState is the state ID to change to if Action returns false.
	FalseState StateIndex

	// SaveNeeded is true if this entry requires a save state event.
	SaveNeeded bool
}

ActionEntry defines a single match and process rule for a state.

func ReadOp

func ReadOp(match int, action ActionFunc) ActionEntry

ReadOp designates a message that is processed in a way that does not require a save action when it completes. Consequently, it also is precluded from changing the current state, as that definitionally requires a save action.

func WriteOp

func WriteOp(
	match int,
	action ActionFunc,
	trueState StateIndex,
	falseState StateIndex) ActionEntry

WriteOp designates a message that requires a save action as the result of the processing it invokes.

type ActionFunc

type ActionFunc func(ctx context.Context, machine *SM, msg Envelope) bool

ActionFunc is the signature definition for a message processing function listed in an ActionEntry.

type ActionState

type ActionState struct {
	NullState

	// Entries is the set of actions that can be taken in this state, with the
	// require incoming message match criteria, and state transitions.
	Entries []ActionEntry

	// Default is the action to take if no item in the Entries array matches
	// the incoming message.
	Default ActionFunc

	// OnEnter is the optional function to call when entering this state
	// (including transition from this state back to this state).
	OnEnter EnterFunc

	// OnLeave is the optional function to call when exiting this state
	// (including transition from this state back to this state).
	OnLeave LeaveFunc
}

ActionState is the common definition for how to process incoming requests for a particular state.

func NewActionState

func NewActionState(
	actions []ActionEntry,
	other ActionFunc,
	onEnter EnterFunc,
	onLeave LeaveFunc) *ActionState

NewActionState creates a new ActionState instance with the supplied match and processing rules.

func (*ActionState) Enter

func (s *ActionState) Enter(ctx context.Context, machine *SM) error

func (*ActionState) Leave

func (s *ActionState) Leave(ctx context.Context, sm *SM, nextState StateIndex)

func (*ActionState) Process

func (s *ActionState) Process(
	ctx context.Context,
	machine *SM,
	msg Envelope) (bool, error)

Process is the standard processing step that finds the appropriate rule and executes it.

func (*ActionState) Receive

func (s *ActionState) Receive(ctx context.Context, machine *SM, msg Envelope) bool

type EnterFunc

type EnterFunc func(ctx context.Context, machine *SM) error

EnterFunc is the signature definition for OnEnter functions.

type Envelope

type Envelope interface {

	// Initialize sets up any linked span information, and the channel to use
	// for any completion responses.
	Initialize(ctx context.Context, tag int, ch chan *Response)

	// Ch returns the response channel.
	Ch() chan *Response

	// Tag returns the type ID to use when matching this message in the
	// action state table.
	Tag() int
}

Envelope is the standard header interface to the messages to a state machine.

type EnvelopeState

type EnvelopeState struct {
	// contains filtered or unexported fields
}

EnvelopeState holds the outer context wrapper state for an incoming request to the state machine. It should be embedded in a message that the state machine will actually process.

func (*EnvelopeState) Ch

func (e *EnvelopeState) Ch() chan *Response

func (*EnvelopeState) Initialize

func (e *EnvelopeState) Initialize(ctx context.Context, tag int, ch chan *Response)
func (e *EnvelopeState) InitializeNoLink(tag int, ch chan *Response)

func (*EnvelopeState) Tag

func (e *EnvelopeState) Tag() int

type LeaveFunc

type LeaveFunc func(ctx context.Context, machine *SM, nextState StateIndex)

LeaveFunc is the signature definition for OnLeave functions. The nextState parameter contains the state ID for the state being transitioned to. This allows for special processing when, for instance, the transition is from the current state back into the current state.

type NullState

type NullState struct{}

NullState is the default implementation of an SM state

func (*NullState) Enter

func (*NullState) Enter(context.Context, *SM) error

Enter is the default (no-action) implementation.

func (*NullState) Leave

func (*NullState) Leave(context.Context, *SM, string)

Leave is the default (no-action) implementation.

func (*NullState) Receive

func (*NullState) Receive(ctx context.Context, machine *SM, msg Envelope) bool

Receive is the default (no-action) implementation.

type Response

type Response struct {
	// Err holds any completion error code, or nil if the request was
	// successful.
	Err error

	// At contains the simulated time tick when the request completed its
	// processing.
	At int64

	// Msg holds any extended results information, or nil if there either is
	// none, or if an error is returned.
	Msg interface{}
}

Response holds the completion response for a processed request, whether it was successful or not.

func FailedResponse

func FailedResponse(occursAt int64, err error) *Response

FailedResponse constructs a failure response message with the correct time, target, and reason.

func SuccessResponse

func SuccessResponse(occursAt int64) *Response

SuccessResponse constructs a success response message with the correct time and target.

func UnexpectedMessageResponse

func UnexpectedMessageResponse(machine *SM, occursAt int64, body interface{}) *Response

UnexpectedMessageResponse constructs a failure response for the case where the incoming request arrives when it is unexpected by the state machine.

type SM

type SM struct {
	common.Guarded

	// CurrentIndex holds the index to the current state
	CurrentIndex StateIndex

	// Current is a pointer to the current state
	Current State

	// FirstState is the index to the starting state
	FirstState StateIndex

	// States holds the map of known state index values to state implementations
	States map[StateIndex]State

	// Parent points to the structure that holds this state machine, and likely
	// holds global context that the state actions need.
	Parent interface{}

	// Terminated is true if the state machine has reached its final state.
	Terminated bool

	// EnteredAt is the simulated time tick when the current state was entered.
	EnteredAt int64

	// Name is the string that can be used to identify this particular instance.
	Name string

	// Saver is the function responsible for saving the state machine state to
	// an external store at the completion of an operation.
	Saver SaveHandler
}

SM defines a simplified state machine structure. It assumes that the issues of concurrency and lifecycle management are handled by some external logic.

func NewSM

func NewSM(parent interface{}, name string, saver SaveHandler, decls ...StateDecl) *SM

NewSM creates a new state machine instance with the associated parent instance reference, as well as the state declarations.

func (*SM) ChangeState

func (sm *SM) ChangeState(ctx context.Context, newState StateIndex) error

ChangeState changes the current state. Leave the old state, try to enter the new state, and declare that state as current if successful.

func (*SM) Receive

func (sm *SM) Receive(ctx context.Context, msg Envelope)

Receive processes an incoming message by routing it to the active state handler. If the resulting action is marked as 'save needed', invoke the save operation.

func (*SM) Savable

func (sm *SM) Savable() (StateIndex, int64, bool, int64)

Savable returns the SM state that can be usefully saved off and later restored as part of implementing a persistent state machine.

func (*SM) Start

func (sm *SM) Start(ctx context.Context) error

Start sets the state machine to its first (starting) state. All state machine start operations must force a save operation, as there is no saved state stored prior to this event.

type SaveHandler

type SaveHandler func(ctx context.Context, machine *SM, starting bool) error

SaveHandler defines the function signature expected from a state machine save handler.

type StartSM

type StartSM struct {
	EnvelopeState
}

StartSM is the message used to signal the start of a state machine.

func NewStartSM

func NewStartSM(ctx context.Context, ch chan *Response) *StartSM

type State

type State interface {

	// Enter is called when a state transition moves to this state
	Enter(ctx context.Context, sm *SM) error

	// Receive is called on the active start implementation when a new
	// incoming message arrives.  It returns true if this is a message that
	// modifies the logical state machine state, such that it requires the
	// contents to be saved.
	Receive(ctx context.Context, machine *SM, msg Envelope) bool

	// Leave is called when a state transition moves away from this state
	Leave(ctx context.Context, sm *SM, nextState StateIndex)
}

State defines the methods used for state actions and transitions.

type StateDecl

type StateDecl func() (bool, StateIndex, State)

StateDecl defines the type expected for a state declaration decorator when creating a new SM instance

func WithFirstState

func WithFirstState(
	name StateIndex,
	onEnter EnterFunc,
	actions []ActionEntry,
	other ActionFunc,
	onLeave LeaveFunc) StateDecl

WithFirstState is a decorator that defines the starting state for the state machine

func WithState

func WithState(
	name StateIndex,
	onEnter EnterFunc,
	actions []ActionEntry,
	other ActionFunc,
	onLeave LeaveFunc) StateDecl

WithState is a decorator that defines a state in the state machine

type StateIndex

type StateIndex interface {
	fmt.Stringer
}

StateIndex denotes that the value is used as an index into the state machine action states.

type StopSM

type StopSM struct {
	EnvelopeState
}

StopSM is the message used to signal the termination of a stat machine.

func NewStopSM

func NewStopSM(ctx context.Context, ch chan *Response) *StopSM

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL