states

package
v0.18.2 Latest Latest
Warning

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

Go to latest
Published: Mar 9, 2026 License: MIT Imports: 4 Imported by: 5

README

/pkg/states

cd /

[!NOTE] asyncmachine-go is a batteries-included graph control flow library (AOP, actor model, state-machine).

/pkg/states contains common state schema mixins to make state-based APIs easier to compose and exchange. It also offers tooling for piping states between state machines.

Available State Schemas

Installation States

import ssam "github.com/pancsta/asyncmachine-go/pkg/states"

Examples

Inherit from BasicStatesDef manually
// inherit BasicSchema
schema := am.SchemaMerge(ssam.BasicSchema, am.Schema{
    "Foo": {Require: am.S{"Bar"}},
    "Bar": {},
})
names := am.SAdd(ssam.BasicStates.Names(), am.S{"Foo", "Bar"})
Inherit from BasicStatesDef via a schema definition
// MyMachStatesDef contains all the states of the MyMach state machine.
type MyMachStatesDef struct {
    *am.StatesBase

    State1 string
    State2 string

    // inherit from BasicStatesDef
    *ss.BasicStatesDef
}

// MyMachSchema represents all relations and properties of MyMachStates.
var MyMachSchema = SchemaMerge(
    // inherit from BasicSchema
    ss.BasicSchema,
    am.Schema{

        ssM.State1: {},
        ssM.State2: {
            Multi: true,
        },
})
Inherit from BasicStatesDef via the generator
$ am-gen --name MyMach \
  --states State1,State2 \
  --inherit basic

Piping

A "pipe" binds a transition handler to a source state-machine and mutates the target state-machine. Only final handlers are subject to piping and the resulting mutation won't block the source transition (it will be queued instead). The target state-machine can reject the mutation, as a part of the negotiation phase.

Pipes work only within the same Golang process, but when combined with /pkg/rpc, we can effectively pipe states over the network. Some packages export predefined pipes for their state machines (eg /pkg/rpc and /pkg/node).

Installation Pipes
import ampipe "github.com/pancsta/asyncmachine-go/pkg/states/pipes"
Predefined Pipes

These predefined functions should cover most of the use cases:

  • BindErr
  • BindReady
  • BindConnected
  • Bind
  • BindMany
  • BindAny
Using Pipes
// pipe RpcReady to RpcReady from rpcClient.Mach to myMach
ampipe.BindReady(rpcClient.Mach, myMach, "RpcReady", "")

// pipe Foo to FooActive and FooInactive from myMach1 to myMach2
ampipe.Bind(myMach1, myMach2, "Foo", "FooActive", "FooInactive")
Piping Manually
var source *am.Machine
var target *am.Machine

h := &struct {
    ReadyState am.HandlerFinal
    ReadyEnd   am.HandlerFinal
}{
    ReadyState: ampipe.Add(source, target, "Ready", "RpcReady"),
    ReadyEnd:   ampipe.Remove(source, target, "Ready", "RpcReady"),
}

source.BindHandlers(h)

Extending States

The purpose of this package is to share reusable schemas, but inheriting a full schema isn't enough. States can also be extended on relations-level using helpers from states_utils.go (generated), although sometimes it's better to override a state (eg Ready).

import (
    am "github.com/pancsta/asyncmachine-go/pkg/machine"
    "github.com/pancsta/asyncmachine-go/pkg/states"
    ampipe "github.com/pancsta/asyncmachine-go/pkg/states/pipes"
)

// ...

MyMychStruct = am.Schema{

    // inject Client states into Connected
    "Connected": StateAdd(
        states.ConnectedStruct[states.ConnectedStates.Connected],
        am.State{
            Remove: S{"RetryingConn"},
            Add:    S{"Handshaking"},
    }),
}

// see state_utils.go

Documentation

Status

Testing, semantically versioned.

monorepo

Go back to the monorepo root to continue reading.

Documentation

Overview

Package states provides reusable state definitions.

- basic - connected - disposed

Index

Constants

This section is empty.

Variables

View Source
var (

	// ConnectedStates contains all the states for the Connected state schema.
	ConnectedStates = ssC

	// ConnectedGroups contains all the state groups for the Connected state
	// schema.
	ConnectedGroups = sgC
)
View Source
var (

	// ConnPoolStates contains all the states for the ConnPool state schema.
	ConnPoolStates = ssPc

	// ConnPoolGroups contains all the state groups for the ConnPool state schema.
	ConnPoolGroups = sgCp
)
View Source
var (

	// DisposedStates contains all the states for the Disposed machine.
	DisposedStates = ssD
	// DisposedGroups contains all the state groups for the Disposed machine.
	DisposedGroups = sgD
)
View Source
var BasicSchema = am.Schema{

	ssB.Exception: {Multi: true},
	ssB.ErrNetwork: {
		Multi:   true,
		Add:     S{Exception},
		Require: S{Exception},
	},
	ssB.ErrHandlerTimeout: {
		Multi:   true,
		Add:     S{Exception},
		Require: S{Exception},
	},

	ssB.Start:       {},
	ssB.Ready:       {Require: S{ssB.Start}},
	ssB.Healthcheck: {Multi: true},
	ssB.Heartbeat:   {},
}
View Source
var (

	// BasicStates contains all the states for the Basic machine.
	BasicStates = ssB
)
View Source
var ConnPoolSchema = am.Schema{
	ssPc.ErrConnecting: {Require: S{Exception}},

	ssPc.Disconnected: {
		Remove: S{ssPc.Connecting, ssPc.ConnectedFully, ssPc.Disconnecting},
	},
	ssPc.Connecting: {
		Require: S{ssB.Start},
		Remove:  S{ssPc.Disconnecting},
	},
	ssPc.Connected: {
		Require: S{ssB.Start},
		Remove:  S{ssPc.Disconnected},
	},
	ssPc.ConnectedFully: {
		Require: S{ssPc.Connected},
		Remove:  S{ssPc.Disconnected},
	},
	ssPc.Disconnecting: {
		Remove: S{ssPc.ConnectedFully, ssPc.Connected, ssPc.Connecting},
	},
}

ConnPoolSchema represents all relations and properties of ConnPoolStates.

View Source
var ConnectedSchema = am.Schema{
	ssC.ErrConnecting: {Require: S{Exception}},

	ssC.Connecting: {
		Require: S{ssB.Start},
		Remove:  sgC.Connected,
	},
	ssC.Connected: {
		Require: S{ssB.Start},
		Remove:  sgC.Connected,
	},
	ssC.Disconnecting: {Remove: sgC.Connected},
	ssC.Disconnected: {
		Auto:   true,
		Remove: sgC.Connected,
	},
}

ConnectedSchema represents all relations and properties of ConnectedStates.

View Source
var DisposedArgHandler = "DisposedArgHandler"

DisposedArgHandler is the key for the disposal handler passed to the RegisterDisposal state. It needs to contain the EXPLICIT type of am.HandlerDispose, eg

var dispose am.HandlerDispose = func(id string, ctx *am.StateCtx) {
	// ...
}
View Source
var DisposedSchema = am.Schema{
	ssD.RegisterDisposal: {Multi: true},
	ssD.Disposing:        {Remove: S{ssB.Start}},
	ssD.Disposed:         {Remove: S{ssD.Disposing, ssB.Start}},
}

DisposedSchema represents all relations and properties of DisposedStates.

View Source
var ErrConnecting = errors.New("error connecting")
View Source
var Exception = am.StateException

Exception is a type alias for the exception state.

View Source
var SAdd = am.SAdd

SAdd is a func alias for merging lists of states.

View Source
var SchemaMerge = am.SchemaMerge

SchemaMerge is a func alias for extending an existing state structure.

View Source
var StateAdd = am.StateAdd

StateAdd is a func alias for adding to an existing state definition.

View Source
var StateSet = am.StateSet

StateSet is a func alias for replacing parts of an existing state definition.

View Source
var StatesUtilsFile string

Functions

func AddErrConnecting added in v0.10.1

func AddErrConnecting(
	event *am.Event, mach *am.Machine, err error, args am.A,
) error

AddErrConnecting wraps an error in the ErrConnecting sentinel and adds to a machine.

Types

type BasicStatesDef added in v0.8.0

type BasicStatesDef struct {
	*am.StatesBase

	// ErrNetwork indicates a generic network error.
	ErrNetwork string
	// ErrHandlerTimeout indicates one of the state machine handlers has timed
	// out.
	ErrHandlerTimeout string

	// Start indicates the machine should be working. Removing start can force
	// stop the machine.
	Start string
	// Ready indicates the machine meets criteria to perform work.
	Ready string
	// Healthcheck is a periodic request making sure that the machine is still
	// alive.
	Healthcheck string
	// Heartbeat is a periodic state that ensures the integrity of the machine.
	Heartbeat string
}

BasicStatesDef contains all the basic states.

type ConnPoolGroupsDef added in v0.10.3

type ConnPoolGroupsDef struct {
	Connected S
}

ConnPoolGroupsDef contains all the state groups of the ConnPool state schema.

type ConnPoolState added in v0.10.3

type ConnPoolState = string

type ConnPoolStatesDef added in v0.10.3

type ConnPoolStatesDef struct {
	// ErrConnecting is a detailed connection error, eg no access.
	ErrConnecting ConnPoolState

	Connecting     ConnPoolState
	Connected      ConnPoolState
	ConnectedFully ConnPoolState
	Disconnecting  ConnPoolState
	Disconnected   ConnPoolState

	*am.StatesBase
}

ConnPoolStatesDef contains states for a connection status. Required states: - Start

type ConnectedGroupsDef added in v0.8.0

type ConnectedGroupsDef struct {
	Connected S
}

ConnectedGroupsDef contains all the state groups of the Connected state schema.

type ConnectedState added in v0.10.3

type ConnectedState = string

type ConnectedStatesDef added in v0.8.0

type ConnectedStatesDef struct {
	// ErrConnecting is a detailed connection error, eg no access.
	ErrConnecting ConnectedState

	Connecting    ConnectedState
	Connected     ConnectedState
	Disconnecting ConnectedState
	Disconnected  ConnectedState

	*am.StatesBase
}

ConnectedStatesDef contains states for a connection status. Required states: - Start

type DisposedGroupsDef added in v0.10.0

type DisposedGroupsDef struct{}

DisposedGroupsDef contains all the state groups Disposed state machine.

type DisposedHandlers added in v0.10.0

type DisposedHandlers struct {
	// DisposedHandlers is a list of handler for pkg/states.DisposedStates
	DisposedHandlers []am.HandlerDispose
}

DisposedHandlers handle disposal and NEEDS to be initialized manually.

  h := &Handlers{
		DisposedHandlers: &ssam.DisposedHandlers{},
  }

func (*DisposedHandlers) DisposedState added in v0.17.0

func (h *DisposedHandlers) DisposedState(e *am.Event)

func (*DisposedHandlers) DisposingState added in v0.10.0

func (h *DisposedHandlers) DisposingState(e *am.Event)

func (*DisposedHandlers) RegisterDisposalEnter added in v0.10.0

func (h *DisposedHandlers) RegisterDisposalEnter(e *am.Event) bool

func (*DisposedHandlers) RegisterDisposalState added in v0.10.0

func (h *DisposedHandlers) RegisterDisposalState(e *am.Event)

RegisterDisposalState registers an external / dynamic disposal handler. Machine handlers should overload DisposingState and call super instead.

type DisposedStatesDef added in v0.10.0

type DisposedStatesDef struct {
	*am.StatesBase

	// RegisterDisposal registers a disposal handler passed under the
	// DisposedArgHandler key. Requires [DisposedHandlers] to be bound prior to
	// the registration. Handlers registered via RegisterDisposal can block.
	RegisterDisposal string
	// Disposing starts the machine disposal - first state-based and then calls
	// [am.Machine.Dispose].
	Disposing string
	// Disposed indicates that the machine has disposed allocated resources
	// and is ready to be garbage collected by calling [am.Machine.Dispose].
	Disposed string
}

DisposedStatesDef contains all the states of the Disposed state machine. One a machine implements this state mixing, it HAS TO be disposed using the Disposing state (instead of am.Machine.Dispose).

Required states: - Start

type S

type S = am.S

S is a type alias for a list of state names.

type State

type State = am.State

State is a type alias for a state definition. See am.State.

Directories

Path Synopsis
Package global should be imported into the package's global scope with:
Package global should be imported into the package's global scope with:
Package pipes provide helpers to pipe states from one machine to another.
Package pipes provide helpers to pipe states from one machine to another.

Jump to

Keyboard shortcuts

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