statum

package module
v0.0.0-...-643ec71 Latest Latest
Warning

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

Go to latest
Published: Jun 3, 2023 License: MIT Imports: 4 Imported by: 0

README

FSM for Golang with generic

Statum is an FSM for Golang with generic for strong type.

Example

From examples/simple:

package main

import (
	"context"
	"log"

	"github.com/nqd/statum"
)

func main() {
	type state string
	type transaction string

	const (
		stateClosed state       = "closed"
		stateOpen   state       = "open"
		tranOpen    transaction = "open"
		tranClose   transaction = "close"
	)

	config := statum.NewStateMachineConfig[state, transaction]().
		AddState(stateOpen, statum.WithPermit(tranClose, stateClosed)).
		AddState(stateClosed, statum.WithPermit(tranOpen, stateOpen))

	fsm, err := statum.NewFSM[state, transaction](stateOpen, config)
	if err != nil {
		log.Panicln("failed to create new fsm", err)
	}

	log.Println("Current state:", fsm.Current())

	err = fsm.Fire(context.Background(), tranClose)
	if err != nil {
		log.Panicln("Failed to create trigger close transaction")
	}

	log.Println("Current state:", fsm.Current())
}

Callbacks

Statum support callbacks when entering/exit a specific state or any state.

a. To add a callback en entering or exit a specific state:

	conf := statum.NewStateMachineConfig[state, transaction]().
		AddState(stateClosed,
			statum.WithPermit(tranOpen, stateOpen),
		).
		AddState(stateOpen,
			statum.WithPermit(tranClose, stateClosed),
			statum.WithOnEnterState(d.enterOpenState),
			statum.WithOnLeaveState(d.leaveOpenState),
		)


func (d *Door) enterOpenState(_ context.Context, e *statum.Event[state, transaction]) {
	// will be called before FSM entering stateOpen state
}

func (d *Door) leaveOpenState(_ context.Context, e *statum.Event[state, transaction]) error {
	// will be called when FSM exit stateOpen state
}

b. To add callbacks when entering/exit any state:

	conf := statum.NewStateMachineConfig[state, transaction]().
		AddState(stateClosed,
			statum.WithPermit(tranOpen, stateOpen),
		).
		AddState(stateOpen,
			statum.WithPermit(tranClose, stateClosed),
		).
		OnEnterAnyState(d.enterState).
		OnLeaveAnyState(d.leaveState)


func (d *Door) enterState(_ context.Context, e *statum.Event[state, transaction]) {
	// will be called when FSM enter any state (stateOpen, stateClosed)
}

func (d *Door) leaveState(_ context.Context, e *statum.Event[state, transaction]) error {
	// will be called when FSM leave any state (stateOpen, stateClosed)
}
Order of callbacks

Order of state callbacks

Cancelling a transition

Any observer can cancel a transition by returning an error during any of the following callbacks:

  • leave a state (WithOnLeaveState)
  • leave any state (OnLeaveAnyState)

Any subsequence registered callbacks will be cancelled and state will remain unchanged.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidTransaction = errors.New("invalid transaction")
	ErrNotRegisteredState = errors.New("state is not registered")
)

Functions

This section is empty.

Types

type Callback

type Callback[S, T constraints.Ordered] func(ctx context.Context, e *Event[S, T]) error

CallbackNoReturn is used as a callback with cancellation ability. Example: WithOnLeaveState, OnLeaveAnyState

type CallbackNoReturn

type CallbackNoReturn[S, T constraints.Ordered] func(ctx context.Context, e *Event[S, T])

CallbackNoReturn is used as a callback with no cancellation ability. Example: WithOnEnterState, OnEnterAnyState

type Config

type Config[S, T constraints.Ordered] struct {
	// contains filtered or unexported fields
}

func NewStateMachineConfig

func NewStateMachineConfig[S, T constraints.Ordered]() *Config[S, T]

func (*Config[S, T]) AddState

func (c *Config[S, T]) AddState(s S, opts ...StateOption[S, T]) *Config[S, T]

func (*Config[S, T]) OnEnterAnyState

func (c *Config[S, T]) OnEnterAnyState(f CallbackNoReturn[S, T]) *Config[S, T]

func (*Config[S, T]) OnLeaveAnyState

func (c *Config[S, T]) OnLeaveAnyState(f Callback[S, T]) *Config[S, T]

type Event

type Event[S, T constraints.Ordered] struct {
	FSM         *FSM[S, T]
	Transaction T
	Src         S
	Dst         S
}

Event is the info that get passed as a reference in the Callback

type FSM

type FSM[S, T constraints.Ordered] struct {
	// contains filtered or unexported fields
}

func NewFSM

func NewFSM[S, T constraints.Ordered](initState S, config *Config[S, T]) (*FSM[S, T], error)

func (*FSM[S, T]) Current

func (f *FSM[S, T]) Current() S

Current returns the current fsm state

func (*FSM[S, T]) Fire

func (f *FSM[S, T]) Fire(ctx context.Context, t T) error

Fire sends a transition trigger to fsm

func (*FSM[S, T]) SetState

func (f *FSM[S, T]) SetState(s S) error

SetState move fsm to given state, do not trigger any Callback

type StateOption

type StateOption[S, T constraints.Ordered] func(property *stateProperty[S, T])

func WithOnEnterState

func WithOnEnterState[S, T constraints.Ordered](f CallbackNoReturn[S, T]) StateOption[S, T]

func WithOnLeaveState

func WithOnLeaveState[S, T constraints.Ordered](f Callback[S, T]) StateOption[S, T]

func WithPermit

func WithPermit[S, T constraints.Ordered](t T, s S) StateOption[S, T]

Directories

Path Synopsis
examples
simple command
struct command

Jump to

Keyboard shortcuts

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