Help us shape the future of Go! Take the 2026 Go Developer Survey

flow

package
v2.17.2 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2026 License: BSD-3-Clause Imports: 24 Imported by: 0

Documentation

Overview

Package flow runs durable multi-step jobs as Francis workflows inside coordinator runs. The run stays the source of truth for status, the Jobs UI, and Activity; the workflow instance is its execution graph.

Migrating a job:

  1. Write each step as a func(ctx context.Context, t flow.Task) (any, error), inline in the definition unless it is shared or too complex to inline. Return common.Classify(common.ErrUnavailable or common.ErrTimeout, err) to retry; other errors fail the task. Tasks run at least once, so confirm external effects before repeating them.
  2. Keep inputs and outputs small: keys, not lists of data, since Francis ships the instance input with every task. Keep data in domain tables and never put secrets in a payload.
  3. Define the workflow with Engine.Define in a RegisterWorkflows method called from the service's DI provider. The last step returns scheduler.Outcome.
  4. Register a flow.Job in place of the old job.
  5. Cover the definition with flowtest.AssertDefinitions. On any graph or policy change, bump Version and set Fingerprint to the value the test reports.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotResumable reports that a run has no workflow instance this host can serve.
	ErrNotResumable = errors.New("workflow instance cannot be resumed")
)

Functions

func Retryable

func Retryable(err error) bool

Retryable reports whether another attempt could succeed. Sources classify transient failures; only network timeouts are assumed transient here.

Types

type Activities

type Activities interface {
	activitylib.Service
	activitylib.MessageAppender
	activitylib.Tracker
	UpdateActivity(ctx context.Context, activityID string, req activitylib.UpdateRequest) (*activitytypes.Activity, error)
	AwaitActivitySlotBounded(ctx context.Context, activityID, environmentID string) error
}

Activities is the activity service surface the engine drives.

type Binding

type Binding struct {
	EnvironmentID string `json:"environmentId,omitempty"`
	JobID         string `json:"jobId,omitempty"`
	RunID         string `json:"runId,omitempty"`
	RootID        string `json:"rootId"`
}

Binding ties an instance, and its children, to the run that started it.

type Definition

type Definition struct {
	Name        string
	Version     int
	Fingerprint string
	Concurrency int
	Timeout     time.Duration
	// Activity is the template for the activity each root instance owns; an empty Type means none.
	Activity activitylib.StartRequest
	// Labels name steps on the activity; steps without one show their name.
	Labels map[string]string
	// Steps use Francis step builders with handlers wrapped by Engine.Handler.
	// The last step returns scheduler.Outcome.
	Steps   []workflow.StepSpec
	Options []workflow.Option
}

Definition declares a workflow. Bump Version and update Fingerprint on any graph or policy change; flowtest.AssertDefinitions reports the new value.

type Engine

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

Engine defines workflows, runs them inside coordinator runs, and owns their activities.

func New

func New(appCtx context.Context, runtime *francis.Runtime, coordinator *runs.Coordinator, activities Activities) (*Engine, error)

New builds an engine whose monitors live until appCtx ends or Stop is called.

func (*Engine) Define

func (e *Engine) Define(def Definition) (*Workflow, error)

Define validates and registers a workflow. It must run before the host starts.

func (*Engine) Handler

func (e *Engine) Handler(fn func(ctx context.Context, t Task) (any, error)) workflow.StepOption

Handler wraps a step handler. Its ctx carries the bound run exactly as a job's Run does, is canceled when the user cancels the root activity, and its errors are classified for Francis retries.

func (*Engine) Ready

func (e *Engine) Ready()

Ready lets standalone tasks run once startup recovery has protected the work Standalone reported.

func (*Engine) Resume

func (e *Engine) Resume(ctx context.Context, wf *Workflow, run scheduler.Run) (scheduler.Outcome, error)

Resume attaches to the run's active instance, or reads the result of one that finished before the run saved it. When the instance is gone or belongs to a version this host no longer serves, a recorded non-failed result is returned; otherwise it returns ErrNotResumable so the job's fallback can run.

func (*Engine) Retire

func (e *Engine) Retire(ctx context.Context, wf *Workflow, run scheduler.Run, reason string) (outcome scheduler.Outcome, finished bool, err error)

Retire cancels the run's unfinished instance without resuming it, such as for a job that was disabled. An instance that finished before the run saved its result reports that result instead, with finished set.

func (*Engine) Run

func (e *Engine) Run(ctx context.Context, wf *Workflow, payload any, activity activitylib.StartRequest, output any) (scheduler.Outcome, error)

Run starts the workflow, or attaches to the run's active instance, and waits for its outcome. A run in ctx (jobcontext.Run) binds the instance to that run; set fields of activity override the definition's activity template; a non-nil output receives the last step's data alongside its scheduler.Outcome fields.

func (*Engine) Standalone

func (e *Engine) Standalone(ctx context.Context) ([]scheduler.Run, error)

Standalone lists unfinished instances started by Submit or an unbound Run as runs of the workflow's name, carrying the targets their tasks recorded, so startup recovery can protect their work.

func (*Engine) Start

func (e *Engine) Start(ctx context.Context) error

Start monitors every unfinished root instance so activities complete without a caller.

func (*Engine) Stop

func (e *Engine) Stop(context.Context) error

Stop ends monitoring; unfinished instances resume on the next Start.

func (*Engine) Submit

func (e *Engine) Submit(ctx context.Context, wf *Workflow, payload any, activity activitylib.StartRequest, evidence ...scheduler.TargetOutcome) (string, error)

Submit starts a standalone instance without waiting for it and returns its ID, which is also its activity's ID. Its tasks record target progress like a run's; evidence is recorded before the instance starts, such as the record it owns.

func (*Engine) Wait

func (e *Engine) Wait(ctx context.Context, wf *Workflow, instanceID string) (scheduler.Outcome, error)

Wait blocks until a submitted instance finishes, ctx ends, or the engine stops.

func (*Engine) Workflows

func (e *Engine) Workflows() []*Workflow

Workflows lists every defined workflow.

type Job

type Job struct {
	Engine   *Engine
	Workflow *Workflow
	JobName  string
	// Payload is every instance's input, such as the entity a per-entity job runs for.
	Payload any
	// Activity overrides the definition's activity template, such as with the entity's name.
	Activity    activitylib.StartRequest
	ScheduleFn  func(ctx context.Context) string
	ShouldRunFn func(ctx context.Context) bool
	// FallbackFn recovers a run whose instance cannot resume; nil fails the run so
	// a retry starts a fresh instance under a new attempt.
	FallbackFn      func(ctx context.Context, previous scheduler.Run) (scheduler.Outcome, error)
	ValidateRetryFn func(ctx context.Context, run scheduler.Run) error
}

Job runs a workflow as a scheduler job. The coordinator's single flight per job and environment already prevents overlapping runs.

func (*Job) Name

func (j *Job) Name() string

Name is the scheduler job name.

func (*Job) Reconcile

func (j *Job) Reconcile(ctx context.Context, previous scheduler.Run) (scheduler.Outcome, error)

Reconcile resumes an interrupted run's instance, falling back to FallbackFn when it cannot be resumed. A job disabled since the run started makes no further changes.

func (*Job) Run

func (j *Job) Run(ctx context.Context) (scheduler.Outcome, error)

Run skips when the job's condition no longer holds, then runs the workflow.

func (*Job) Schedule

func (j *Job) Schedule(ctx context.Context) string

Schedule is the job's current cron expression.

func (*Job) ShouldSchedule

func (j *Job) ShouldSchedule(ctx context.Context) bool

ShouldSchedule reports whether the job runs; a nil ShouldRunFn always does.

func (*Job) ValidateRetry

func (j *Job) ValidateRetry(ctx context.Context, run scheduler.Run) error

ValidateRetry rejects a retry that ValidateRetryFn reports unsafe.

type Result

type Result[T any] struct {
	Value T
	Err   string
}

Result is one fan-out slot: the task's output, or the error that failed it.

func Results

func Results[T any](t Task, step string) ([]Result[T], error)

Results decodes a fan-out step's output slot by slot. Francis encodes a failed slot as an object whose only key is "error", so successful outputs must never have that shape.

type Task

type Task struct {
	workflow.Task
	// contains filtered or unexported fields
}

Task is what an engine handler receives: the Francis task plus its binding.

func (Task) ActivityID

func (t Task) ActivityID() string

ActivityID returns the activity owned by the task's root instance.

func (Task) ChildInput

func (t Task) ChildInput(payload any) (any, error)

ChildInput returns the output for a step that precedes a Child step, so the child inherits this instance's run binding.

func (Task) Payload

func (t Task) Payload(into any) error

Payload decodes the instance payload.

func (Task) Recovered

func (t Task) Recovered() bool

Recovered reports a standalone task whose instance an earlier process started, so no caller is waiting on it and the request's own checks did not run in this process.

type Workflow

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

Workflow is a defined workflow registered on the engine's host.

func (*Workflow) Fingerprint

func (w *Workflow) Fingerprint() string

Fingerprint is the graph hash the definition declares for its version.

func (*Workflow) Francis

func (w *Workflow) Francis() *workflow.Workflow

Francis exposes the underlying definition for use with workflow.WithChild.

Directories

Path Synopsis
Package flowtest runs workflow engines on isolated Francis hosts for tests.
Package flowtest runs workflow engines on isolated Francis hosts for tests.

Jump to

Keyboard shortcuts

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