workflow

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Jun 1, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package workflow is a state-machine engine with persistent checkpoints: a running instance can crash, restart, and resume from its last recorded state without losing position in the flow.

Distinct from kit/fsm, which is purely in-memory: workflow adds a Store, idempotent event delivery, compensation hooks for rollback, and a Resume entrypoint for picking up in-flight instances after a process restart.

Use cases:

  • Order processing / shipping pipelines.
  • KYC / payment-authorisation multi-step flows.
  • CI run state, deployment pipelines.
  • Game encounter state with mid-encounter persistence.

State and Event must be string-aliased types so that transitions can be safely serialised. The package ships an in-memory Store; Postgres and other backends plug in behind the Store interface.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUnknownInstance   = errors.New("workflow: unknown instance")
	ErrIllegalTransition = errors.New("workflow: illegal transition")
	ErrAlreadyStarted    = errors.New("workflow: instance already started")
)

Errors surfaced by the manager.

View Source
var ErrInstanceMissing = errors.New("workflow: instance not found")

ErrInstanceMissing is returned when CurrentState is called for an instance that was never started.

Functions

This section is empty.

Types

type Edge

type Edge[S ~string, E ~string] struct {
	From  S
	Event E
	To    S
	Guard func(ctx context.Context, id WorkflowID) bool
}

Edge is one transition rule.

type Idempotency

type Idempotency string

Idempotency is a client-supplied key that makes Send safe to retry.

type Manager

type Manager[S ~string, E ~string] struct {
	// contains filtered or unexported fields
}

Manager drives workflow instances against a backing Store.

func NewManager

func NewManager[S ~string, E ~string](spec Spec[S, E], store Store) *Manager[S, E]

NewManager constructs a Manager from a Spec and Store.

func (*Manager[S, E]) Compensate

func (m *Manager[S, E]) Compensate(ctx context.Context, id WorkflowID, toState S) error

Compensate walks history backwards from the current state until `toState` (inclusive of leaving the current state, exclusive of entering `toState` itself) and invokes each Compensator. Useful when a downstream failure forces the workflow to undo recent transitions.

func (*Manager[S, E]) Resume

func (m *Manager[S, E]) Resume(_ context.Context) error

Resume is a hook for process startup to do any housekeeping on in-flight instances (the Store may need to load state into memory). The default implementation is a no-op — workflow state lives in the store and is read on-demand. Callers can override per-instance recovery by extending the Store.

func (*Manager[S, E]) Send

func (m *Manager[S, E]) Send(ctx context.Context, id WorkflowID, ev E, key Idempotency) error

Send delivers an event to the workflow. The transition (if any) is persisted before OnExit/OnEnter run, so a crash mid-callback is recoverable via Resume.

func (*Manager[S, E]) SetClock

func (m *Manager[S, E]) SetClock(f func() time.Time)

SetClock overrides the wall clock; useful for tests.

func (*Manager[S, E]) Start

func (m *Manager[S, E]) Start(ctx context.Context, id WorkflowID) error

Start begins a new workflow instance at the spec's initial state.

func (*Manager[S, E]) State

func (m *Manager[S, E]) State(ctx context.Context, id WorkflowID) (S, error)

State returns the current state of an instance.

type MemoryStore

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

MemoryStore is an in-process Store. Goroutine-safe.

func NewMemoryStore

func NewMemoryStore() *MemoryStore

NewMemoryStore constructs an empty MemoryStore.

func (*MemoryStore) CurrentState

func (s *MemoryStore) CurrentState(_ context.Context, id WorkflowID) (string, error)

CurrentState implements Store.

func (*MemoryStore) History

func (s *MemoryStore) History(_ context.Context, id WorkflowID) ([]Transition, error)

History implements Store.

func (*MemoryStore) SaveTransition

func (s *MemoryStore) SaveTransition(_ context.Context, id WorkflowID, t Transition) error

SaveTransition implements Store.

type Spec

type Spec[S ~string, E ~string] struct {
	Initial     S
	Transitions []Edge[S, E]
	OnEnter     map[S]func(ctx context.Context, id WorkflowID) error
	OnExit      map[S]func(ctx context.Context, id WorkflowID) error
	// Compensators run during Compensate(); each Compensator unwinds the
	// effect of *entering* its state.
	Compensators map[S]func(ctx context.Context, id WorkflowID) error
}

Spec defines the workflow shape. State and Event are constrained to ~string so they can be persisted as-is.

type Store

type Store interface {
	SaveTransition(ctx context.Context, id WorkflowID, t Transition) error
	CurrentState(ctx context.Context, id WorkflowID) (string, error)
	History(ctx context.Context, id WorkflowID) ([]Transition, error)
}

Store persists workflow transitions and exposes per-instance current state and history.

type Transition

type Transition struct {
	From string
	To   string
	Ev   string
	At   time.Time
}

Transition captures a single state change applied to an instance.

type WorkflowID

type WorkflowID string

WorkflowID uniquely identifies a workflow instance.

Jump to

Keyboard shortcuts

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