effect

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Oct 4, 2026 License: MIT Imports: 1 Imported by: 0

Documentation

Overview

Package effect defines the work an actor asks its host to run: delayed transitions (PendingTimer) and invocations (Invocation, PendingInvocation).

The engine never runs an effect itself. It records the intent, the host reads it from engine.Actor, and reports the outcome back by ID.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Invocation

type Invocation[Ctx any, Evt any] struct {
	// ID is unique within its state; combined with the state path it forms the
	// invocation's stable [InvokeID].
	ID string
	// Src is the opaque logical name of the work to run.
	Src string
	// Input, if non-nil, builds the invocation input from the context captured
	// when the state is entered. Exposed to the adapter via PendingInvocation.
	Input func(ctx Ctx) any
	// OnDone, if non-nil, maps a successful result to an event the machine then
	// processes. If nil, a successful resolution is dropped.
	OnDone func(output any) Evt
	// OnError, if non-nil, maps a failure to an event the machine then
	// processes. If nil, a failure is dropped.
	OnError func(err error) Evt
}

Invocation declares external work a state runs while it is active — XState's invoke. The fate core treats Src as an opaque name and never executes it: on entering the state the core records a pending invocation; on exit it disarms it. An adapter discovers pending invocations via engine.Actor.PendingInvocations, runs the work named by Src, and reports the outcome via engine.Actor.ResolveInvocation or engine.Actor.RejectInvocation. The core then maps the outcome to an event (OnDone / OnError) and processes it — but only if the owning state is still active.

Because Src is opaque, the same mechanism expresses both a service/activity call and a spawned child machine: the adapter decides what Src means (a Temporal activity, a child workflow, a nested actor). See ADR-0004.

type InvokeID

type InvokeID string

InvokeID identifies one armed invocation instance for as long as its state is active. It is derived deterministically from the owning state's path and the invocation's local ID, so the same logical invocation has the same ID across runs and across persistence.

type PendingInvocation

type PendingInvocation struct {
	// ID is the invocation's stable identifier.
	ID InvokeID
	// Src is the opaque work name declared on the Invocation.
	Src string
	// Input is the payload built from context at arm time (nil if no Input fn).
	Input any
	// State is the dot path of the state that declares the invocation. A host
	// that sees that state exited in an engine.Step restarts the work.
	State string
}

PendingInvocation is what an adapter reads from engine.Actor.PendingInvocations to learn which work to run. ID is passed back to ResolveInvocation / RejectInvocation when the work settles.

type PendingTimer

type PendingTimer struct {
	// ID is the timer's stable identifier, passed back to engine.Actor.FireTimer.
	ID TimerID
	// Delay is the configured delay of the underlying after-transition. An
	// adapter that resumes a persisted actor is responsible for tracking how
	// much of the delay has already elapsed.
	Delay time.Duration
	// State is the dot path of the state that declares the delay. A host that
	// sees that state exited in an engine.Step restarts the timer.
	State string
}

PendingTimer describes one delayed ("after") transition the actor currently has armed. It is what an adapter reads from engine.Actor.PendingTimers to learn which timers to drive; when the adapter decides a delay has elapsed it calls engine.Actor.FireTimer with the ID.

The fate core is clock-agnostic: it never sleeps, reads the wall clock, or starts a goroutine for a timer. It only records that a state wants to fire "after Delay" and exposes that intent. How and when the timer actually fires is entirely the adapter's responsibility (a Temporal adapter maps it to workflow.NewTimer; an in-memory adapter maps it to the OS clock; a test drives it by hand).

type TimerID

type TimerID string

TimerID uniquely identifies one armed delayed ("after") transition for as long as it is pending. It is derived deterministically from the owning state's path, the delay, and the delay's index within that state, so the same logical timer keeps the same ID across runs and across persistence — a prerequisite for replay-safe driving by an adapter.

Jump to

Keyboard shortcuts

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