Documentation
¶
Overview ¶
Package workflow runs durable workflows whose runners are ordinary Go functions.
Workflows and runners ¶
A workflow is a struct type that embeds Struct[Out], or has its own Workflow(Out) method, to declare the workflow's output. Its package path and type name are the workflow name, and a value of it is the input of a run, so code can Start a workflow from the type alone.
A runner executes the workflow. It is a function func(context.Context, In) (Out, error) registered with Use, and it calls steps through Step, Background, Map, and All. Steps do the real work and side effects.
Runs ¶
Start begins a run of a workflow and returns a Run handle. Every run is recorded in a World, the backend that stores its history, queues its deliveries, and holds its streams.
A run executes in one of two contexts. In workflow context, the runner's own code executes as a flow, which replays the runner from the beginning, records the operations it starts (steps, timers, hooks, webhooks, and child runs), queues the steps it needs, and records the run's result once the runner returns. In step context, a step function executes as a step, which replays the runner up to that step and calls the step function.
Replay ¶
Operations return promises. Once an operation is recorded, replay returns its recorded result instead of running it again, and awaiting a promise that has not settled suspends the run until it does.
A runner must therefore be deterministic. It does side effects only through steps and reads time only through Now. Steps may retry and are executed at least once, so step functions should be idempotent. Package check reports runners that break these rules.
Clients ¶
Code outside a run uses a Client, carried in a context by NewContext or Middleware, to start, read, cancel, and resume runs.
Index ¶
- Constants
- Variables
- func All[In, Out any](ctx context.Context, step func(context.Context, In) (Out, error), inputs []In) ([]Out, error)
- func CancelAny(ctx context.Context, sources ...context.Context) context.Context
- func CancelFunc(ctx context.Context) (func() error, bool)
- func FatalError(cause error) error
- func InlineStep[In, Out any](ctx context.Context, fn func(context.Context, In) (Out, error), input In, ...) (Out, error)
- func Join(ctx context.Context, results ...promise) error
- func JoinOk(ctx context.Context, results ...promise) error
- func MapResults[T any](results []*Result[T]) []promise
- func Middleware(handler http.Handler, client Client) http.Handler
- func NewContext(ctx context.Context, client Client) context.Context
- func NewHookToken() string
- func Now(ctx context.Context) (time.Time, error)
- func ResumeHook[T any](ctx context.Context, token string, value T) error
- func ResumeHookWithRetries[T any](ctx context.Context, token string, value T, attempts int, ...) error
- func RetryableError(cause error, after time.Duration) error
- func Rollback[In any](ctx context.Context, fn func(context.Context, In) error, input In, ...)
- func Select(ctx context.Context, results ...promise) (promise, error)
- func SelectOk(ctx context.Context, results ...promise) (promise, error)
- func SetMaxInlineSteps(ctx context.Context, n int) context.Context
- func SetMaxInlineStepsDuration(ctx context.Context, d time.Duration) context.Context
- func Sleep(ctx context.Context, duration time.Duration) error
- func Step[In, Out any](ctx context.Context, fn func(context.Context, In) (Out, error), input In, ...) (Out, error)
- func StepID(ctx context.Context) string
- func Use[In worlds.Workflow[Out], Out any](fn func(context.Context, In) (Out, error)) worlds.Runner
- func WithCancel(ctx context.Context) (context.Context, func() error, error)
- func WithCancelCause(ctx context.Context) (context.Context, func(error) error, error)
- func WithDeadline(ctx context.Context, deadline time.Time) (context.Context, func() error, error)
- func WithDeadlineCause(ctx context.Context, deadline time.Time, cause error) (context.Context, func() error, error)
- func WithTimeout(ctx context.Context, duration time.Duration) (context.Context, func() error, error)
- func WithTimeoutCause(ctx context.Context, duration time.Duration, cause error) (context.Context, func() error, error)
- func Writer(ctx context.Context, options ...WriterOption) (io.WriteCloser, func() error, error)
- type Client
- type ErrGroup
- type Error
- type Hook
- func (h *Hook[T]) Dispose(ctx context.Context)
- func (h *Hook[T]) GetConflict(ctx context.Context) (*Run[any], error)
- func (h *Hook[T]) ID() string
- func (h *Hook[T]) Next(ctx context.Context) (T, error)
- func (h *Hook[T]) Token() string
- func (h *Hook[T]) Values(ctx context.Context) iter.Seq2[T, error]
- type HookDefinition
- type HookOption
- type ReaderOption
- type Result
- func Background[In, Out any](ctx context.Context, fn func(context.Context, In) (Out, error), input In, ...) *Result[Out]
- func Go[In, Out any](ctx context.Context, g group, step func(context.Context, In) (Out, error), ...) *Result[Out]
- func InlineBackground[In, Out any](ctx context.Context, fn func(context.Context, In) (Out, error), input In, ...) *Result[Out]
- func Map[In, Out any](ctx context.Context, step func(context.Context, In) (Out, error), inputs []In) []*Result[Out]
- func NewResult[T any](value T, err error) *Result[T]
- func Then[T, U any](ctx context.Context, source *Result[T], fn func(T, error) *Result[U]) *Result[U]
- func Timer(ctx context.Context, duration time.Duration) *Result[struct{}]
- type Run
- func (r *Run[Out]) Cancel(ctx context.Context) error
- func (r *Run[Out]) Exists(ctx context.Context) (bool, error)
- func (r *Run[Out]) ID() string
- func (r *Run[Out]) Reader(ctx context.Context, options ...ReaderOption) (StreamReader, error)
- func (r *Run[Out]) Status(ctx context.Context) (Status, error)
- func (r *Run[Out]) Value(ctx context.Context) (Out, error)
- func (r *Run[Out]) WakeUp(ctx context.Context, options ...WakeOptions) (int, error)
- func (r *Run[Out]) WorkflowName(ctx context.Context) (string, error)
- func (r *Run[Out]) Writer(ctx context.Context, options ...WriterOption) (io.WriteCloser, func() error, error)
- type StartOnLatest
- type Status
- type StepMetadata
- type StepOptions
- type StreamChunk
- type StreamReader
- type Struct
- type WaitGroup
- type WakeOptions
- type Webhook
- type WebhookOption
- type WebhookRequest
- type WorkflowMetadata
- type World
- type WriterOption
Constants ¶
const ( // StatusPending means the run or step is recorded but has not started. StatusPending = worlds.StatusPending // StatusRunning means the run or step has started and has not finished. StatusRunning = worlds.StatusRunning // StatusCompleted means the run or step finished with an output. StatusCompleted = worlds.StatusCompleted // StatusFailed means the run or step finished with an error. StatusFailed = worlds.StatusFailed // StatusCancelled means the run or step was cancelled before it finished. StatusCancelled = worlds.StatusCancelled )
Variables ¶
var ( // ErrNoClient reports that the context has no client. ErrNoClient = errors.New("workflow: context has no client") // ErrNoWorkflow reports that an operation requires workflow context. ErrNoWorkflow = errors.New("workflow: context has no active workflow") // ErrNilResult reports a nil result where an operation's result was expected. ErrNilResult = errors.New("workflow: nil result") // ErrNotInStep reports that an operation cannot be called in workflow context. ErrNotInStep = errors.New("workflow: must be called inside a step") // ErrRunCancelled is returned when awaiting a run that was cancelled. ErrRunCancelled = worlds.ErrRunCancelled // ErrResumeNotQueued reports that a hook payload was recorded but its run was not queued. ErrResumeNotQueued = worlds.ErrResumeNotQueued // ErrRunNotFinished reports that a run is still waiting or running. ErrRunNotFinished = errors.New("workflow: run has not finished") // ErrHookNotFound reports that no active hook owns the requested token. ErrHookNotFound = worlds.ErrHookNotFound // ErrHookNotActive reports that a hook can no longer receive payloads. ErrHookNotActive = worlds.ErrHookNotActive // ErrHookNotRegistered reports that a hook does not belong to the current // workflow execution. ErrHookNotRegistered = errors.New("workflow: hook is not registered") // ErrHookConflict is returned when claiming a hook whose token another // active hook already has. Hook.GetConflict reports the run that owns it. ErrHookConflict = worlds.ErrHookConflict // ErrHookForceClaimed reports that another hook took over this hook's token. ErrHookForceClaimed = worlds.ErrHookForceClaimed )
Functions ¶
func All ¶
func All[In, Out any](ctx context.Context, step func(context.Context, In) (Out, error), inputs []In) ([]Out, error)
All starts every step and collects successful values in input order. If any step fails, it cancels the others and returns that failure.
func CancelAny ¶
CancelAny retains ctx's values and cancels when ctx or a source cancels. Outside workflow context, it returns ctx unchanged.
func CancelFunc ¶
CancelFunc returns the controller carried by a managed step context.
func FatalError ¶
FatalError wraps cause so that a step returning it fails without retrying. It returns nil when cause is nil.
func InlineStep ¶
func InlineStep[In, Out any](ctx context.Context, fn func(context.Context, In) (Out, error), input In, options ...StepOptions) (Out, error)
InlineStep calls the step fn with input as an inline step and waits for it. It is InlineBackground followed by Value. It behaves like Step, except that the flow always runs it, and its retries, itself, never as a step delivery. It returns the step's final error as an *Error, and ErrNoWorkflow when ctx does not belong to a run.
Use InlineStep for short work that rarely fails, such as generating an ID or reading another run, and Step for anything else. fn is executed at least once, so it should be idempotent or free of side effects.
func JoinOk ¶
JoinOk waits for every input to succeed and returns the first recorded failure. It does not cancel the remaining inputs when one fails.
func MapResults ¶
MapResults converts results to promise inputs, preserving their order.
func Middleware ¶
Middleware returns an http.Handler that serves each request with handler, adding client to the request context as NewContext does.
func NewContext ¶
NewContext returns a copy of ctx that carries client. Start, Get, GetHook, ResumeHook, and Run methods use it, and in step context it takes precedence over the World that records the run.
func NewHookToken ¶
func NewHookToken() string
NewHookToken returns a random 21-character hook token. DefineHook generates replay-stable tokens when HookOption.Token is empty.
func Now ¶
Now returns the current time in UTC, recorded the first time it runs so that replay returns the same time. In workflow context, a runner reads time only through Now, never time.Now. Now returns ErrNoWorkflow outside workflow context, including step context, where time.Now is safe to use.
func ResumeHook ¶
ResumeHook resumes the active hook with token, sending value as its payload encoded as JSON, and queues a delivery so its run resumes. It uses the Client in ctx and returns ErrHookNotFound when no active hook has the token. It is for steps and external callers; workflow context returns ErrNotInStep.
func ResumeHookWithRetries ¶
func ResumeHookWithRetries[T any](ctx context.Context, token string, value T, attempts int, interval time.Duration) error
ResumeHookWithRetries attempts ResumeHook up to attempts times, waiting interval between attempts while it returns ErrHookNotFound. The first attempt is immediate. Use it when a run may not have registered its hook yet, such as right after Start. It stops when ctx is done and rejects workflow context with ErrNotInStep.
func RetryableError ¶
RetryableError wraps cause so that a step returning it is retried no sooner than after, while StepOptions.MaxRetries allows another retry. It returns nil when cause is nil.
func Rollback ¶
func Rollback[In any](ctx context.Context, fn func(context.Context, In) error, input In, options ...StepOptions)
Rollback registers fn with input as a durable compensation for workflow failure. Defer it after the work it reverses. Compensations run in registration order and retry according to options. It panics with ErrNoWorkflow outside workflow context.
func SetMaxInlineSteps ¶ added in v0.3.0
SetMaxInlineSteps returns a copy of ctx that sets how many new steps a flow runs inline at once, instead of queueing a step delivery for each. The default is 3. Zero runs none inline, and other values are clamped to 1 through 16. Steps beyond the limit are queued as usual.
Set it on the ctx a World's handler executes deliveries with to set the limit for that worker, or in a runner for the steps it declares with the returned ctx.
func SetMaxInlineStepsDuration ¶ added in v0.5.1
SetMaxInlineStepsDuration returns a copy of ctx that sets how long after a flow delivery starts it may start new steps inline. The default is 2 minutes, and zero starts none inline. After it, new steps are queued, so a long-running flow hands them to other deliveries.
A flow also stops starting steps inline halfway to the deadline of the ctx it executes with, so the steps it started can finish before it.
Set it like SetMaxInlineSteps: on the ctx a World's handler executes deliveries with, or in a runner for the steps it declares with the returned ctx.
func Sleep ¶
Sleep suspends the run for duration. Use it instead of time.Sleep in a workflow. It is Timer followed by Value.
func Step ¶
func Step[In, Out any](ctx context.Context, fn func(context.Context, In) (Out, error), input In, options ...StepOptions) (Out, error)
Step calls the step fn with input from a workflow and returns its result, suspending the run until the step has settled. Step is Background followed by Value. It returns ErrNoWorkflow when ctx does not belong to a run.
When the step fails, Step returns the step's error as an *Error, which errors.Is and errors.As match against the error the step returned.
func StepID ¶
StepID returns the ID of the step ctx belongs to, or "" outside step context. It is shorthand for GetStepMetadata(ctx).ID.
func Use ¶
Use registers fn as the runner of workflow In. Pass the returned Runner to worlds.Runners so the runtime can execute the workflow. The workflow name is the package path and type name of In. fn replays on every delivery, so it must be deterministic. It does side effects only through steps and reads time only through Now.
func WithCancel ¶
WithCancel creates a durable cancellation context in workflow context. It returns ErrNoWorkflow outside workflow context.
func WithCancelCause ¶
WithCancelCause creates a durable cancellation context whose first cancellation cause wins. It returns ErrNoWorkflow outside workflow context.
func WithDeadline ¶
WithDeadline creates a durable cancellation context that is cancelled at deadline. Expiry sets context.Cause to context.DeadlineExceeded; manual cancellation uses context.Canceled. Cancellation affects steps and timers using the context, and does not cancel runs. It returns ErrNoWorkflow outside workflow context.
func WithDeadlineCause ¶
func WithDeadlineCause(ctx context.Context, deadline time.Time, cause error) (context.Context, func() error, error)
WithDeadlineCause is WithDeadline with a custom expiry cause. A nil cause uses context.DeadlineExceeded. Manual cancellation uses context.Canceled and disarms the timer.
func WithTimeout ¶
func WithTimeout(ctx context.Context, duration time.Duration) (context.Context, func() error, error)
WithTimeout creates a durable cancellation context that is cancelled after duration. The cancel function cancels the context early and disarms its timer. It returns ErrNoWorkflow outside workflow context.
func WithTimeoutCause ¶
func WithTimeoutCause(ctx context.Context, duration time.Duration, cause error) (context.Context, func() error, error)
WithTimeoutCause is WithTimeout with a custom expiry cause. A nil cause uses context.DeadlineExceeded. Manual cancellation uses context.Canceled and disarms the timer.
func Writer ¶
func Writer(ctx context.Context, options ...WriterOption) (io.WriteCloser, func() error, error)
Writer returns a writer for a stream of the run ctx belongs to. It must be called in step context. It returns ErrNotInStep in workflow context and ErrNoWorkflow outside a run.
The writer holds the stream name, so Writer waits while another writer holds it. Close closes the stream for all writers, while the returned release function only gives up this writer's hold so a retry or another step can continue the stream.
Types ¶
type Client ¶
Client is the API for starting, reading, cancelling, and resuming runs, and for reading and writing their streams, from outside a run.
func NewHTTPClient ¶
NewHTTPClient returns a Client that calls a World served by worlds.HTTPHandler. endpoint is the absolute URL of the server followed by the handler's prefix, such as http://worker:8081/v1/workflow. It panics when endpoint is not an absolute HTTP URL. Requests use the last of clients, or http.DefaultClient when none is given.
type ErrGroup ¶
type ErrGroup struct {
// contains filtered or unexported fields
}
ErrGroup waits for all its members and returns their first recorded failure. Its zero value is ready to use without cancellation. ErrGroupWithContext enables cancellation. After completion, the outcome stays fixed and new work is ignored. Create a new ErrGroup to wait for more work.
func ErrGroupWithContext ¶
ErrGroupWithContext returns an ErrGroup and a durable cancellation context. The group begins observing members when first awaited. Its context is cancelled on the first observed failure or when Wait returns. It returns ErrNoWorkflow outside workflow context.
type Error ¶
Error represents a recorded failure. It keeps the type, message, and exported fields of each error in the original chain, so errors.Is matches sentinel errors and errors.As decodes error types after replay.
type Hook ¶
type Hook[T any] struct { // ClaimedFrom identifies the previous owner of a force-claimed token. ClaimedFrom *worlds.HookForceClaim // contains filtered or unexported fields }
Hook receives repeated typed payloads addressed by its token.
func CreateHook ¶
func CreateHook[T any](ctx context.Context, options ...HookOption) *Hook[T]
CreateHook creates an unregistered hook handle for payloads of type T. It is DefineHook followed by Create.
func GetHook ¶
GetHook looks up the active hook with token using the Client in ctx. It returns false when no active hook has the token. The returned Hook only reports identity and claim metadata, and it cannot be awaited. It is for steps and external callers; workflow context returns ErrNotInStep.
func (*Hook[T]) Dispose ¶
Dispose durably deactivates the hook and releases its token. It may be deferred and panics on failure.
func (*Hook[T]) GetConflict ¶
GetConflict registers the hook and attempts to claim its token, without waiting for a payload. It returns the conflicting owner, or nil on success. Repeated calls return the recorded result without attempting another claim.
type HookDefinition ¶
type HookDefinition[T any] struct { // contains filtered or unexported fields }
HookDefinition is a hook declared with DefineHook but not yet created in a run. Receiving or selecting registers it; GetConflict waits only for ownership.
func DefineHook ¶
func DefineHook[T any](options ...HookOption) HookDefinition[T]
DefineHook declares a hook that receives a payload of type T. The last of options applies. An empty token is generated when the handle is created.
func (HookDefinition[T]) Create ¶
func (d HookDefinition[T]) Create(ctx context.Context) *Hook[T]
Create creates a hook handle in workflow context without claiming its token. Receiving or selecting this hook registers it. Use GetConflict to claim ownership before starting work that depends on the token. Outside workflow context, the handle reports ErrNoWorkflow when used.
type HookOption ¶
type HookOption struct {
// Token is the hook token callers pass to ResumeHook. When empty, a
// token is generated at creation and kept across replays.
Token string
// MinRetention reserves the token until creation time plus this duration,
// including after run completion. Explicit Dispose releases it immediately.
MinRetention time.Duration
// Force takes the token over from another run's active hook instead of
// failing with ErrHookConflict. Awaiting the displaced hook returns
// ErrHookForceClaimed.
Force bool
}
HookOption holds the options to DefineHook and CreateHook.
type ReaderOption ¶
type ReaderOption struct {
// Name is the stream name. The zero value names the run's default stream.
Name string
// StartIndex is the index of the chunk to start reading at. Each write is
// one chunk. A negative StartIndex counts back from the end of the
// stream, so -3 reads the last three chunks.
StartIndex int
}
ReaderOption holds the options to Reader and Run.Reader.
type Result ¶
type Result[T any] struct { // contains filtered or unexported fields }
Result holds the outcome of a background step, timer, or continuation. Reading a pending result suspends the workflow until it settles.
func Background ¶
func Background[In, Out any](ctx context.Context, fn func(context.Context, In) (Out, error), input In, options ...StepOptions) *Result[Out]
Background starts the step fn with input from a workflow and returns a promise for its result without waiting for it. Outside workflow context, the promise fails with ErrNoWorkflow.
The step is identified by fn's function name and its position in the runner. It is retried on error according to options, where the last option applies and the default allows 3 retries. fn is executed at least once and should be idempotent.
func Go ¶
func Go[In, Out any](ctx context.Context, g group, step func(context.Context, In) (Out, error), input In, options ...StepOptions) *Result[Out]
Go starts a background step and adds its result to group. It returns nil without starting a step if the group has completed.
func InlineBackground ¶ added in v0.3.0
func InlineBackground[In, Out any](ctx context.Context, fn func(context.Context, In) (Out, error), input In, options ...StepOptions) *Result[Out]
InlineBackground starts the step fn with input as an inline step and returns a promise for its result without waiting for it, like Background. When the runner waits, the flow runs it, at the same time as the other steps it runs inline, and the runner continues as each one finishes. It always runs inline, whatever SetMaxInlineSteps allows, and a retry runs in a later flow once it is due. Outside workflow context, the promise fails with ErrNoWorkflow.
func Map ¶
func Map[In, Out any](ctx context.Context, step func(context.Context, In) (Out, error), inputs []In) []*Result[Out]
Map starts one background step per input, returning results in input order.
func Then ¶
func Then[T, U any](ctx context.Context, source *Result[T], fn func(T, error) *Result[U]) *Result[U]
Then follows the result returned by fn after source settles. The callback runs in workflow context during replay. Return pending work without waiting inside the callback so other Select inputs can still win. A nil result from fn settles the chain with ErrNilResult.
func Timer ¶
Timer returns a timer, which is a promise that settles after duration. Outside workflow context, the promise fails with ErrNoWorkflow.
type Run ¶
type Run[Out any] struct { // contains filtered or unexported fields }
Run is a handle to a run of a workflow whose output type is Out. Start and Get return one. A Run has an independent lifetime; use Cancel to cancel it.
A Run started in workflow context is a child run. In workflow context, every Run method reads or changes the run once in an inline step and replay returns the recorded result, so a method does not wait for the run to finish. Value returns ErrRunNotFinished for a run that had not finished when it was called. These inline steps do not inherit managed context cancellation. To wait for a child run, create a hook and have the child resume it.
func Get ¶
Get returns a handle to the run with runID, using the Client in ctx. It does not check that the run exists (see Run.Exists). It returns ErrNoClient when ctx carries no Client and does not belong to a run.
func Start ¶
Start starts a run of workflow In with input and returns a handle to the run without waiting for it. It needs only the workflow type, not its runner.
Called in workflow context, Start starts a child run in a step, so replay returns the same run. The child run carries worlds.ParentRunIDAttribute and worlds.RootRunIDAttribute. Cancellation of ctx does not cancel the child; use Run.Cancel explicitly. Called elsewhere, it uses the Client in ctx and returns ErrNoClient when ctx carries none.
func (*Run[Out]) Cancel ¶
Cancel cancels the run. Cancelling a run that has already finished is a no-op.
func (*Run[Out]) Reader ¶
func (r *Run[Out]) Reader(ctx context.Context, options ...ReaderOption) (StreamReader, error)
Reader returns a reader for the run's stream from ReaderOption.StartIndex, for step context and for use outside a run, such as a route handler. Reads block until data is written and return io.EOF once the stream is closed. It returns ErrNotInStep in workflow context.
func (*Run[Out]) Status ¶
Status returns the current status of the run. It returns worlds.ErrRunNotFound when the run does not exist.
func (*Run[Out]) Value ¶
Value returns the output of the run once it has finished. It returns the run's error as an *Error when the run failed and ErrRunCancelled when it was cancelled.
In workflow context, Value reads the run once and returns ErrRunNotFinished when the run had not finished, so replay stays deterministic. In step context and outside a run, it blocks until the run finishes or ctx is done.
func (*Run[Out]) WakeUp ¶
WakeUp settles the run's pending timers early. It queues a delivery so the run resumes, and returns the number of timers it settled. Waking a deadline timer triggers its cancellation continuation.
func (*Run[Out]) WorkflowName ¶
WorkflowName returns the name of the workflow the run executes. It returns worlds.ErrRunNotFound when the run does not exist.
func (*Run[Out]) Writer ¶
func (r *Run[Out]) Writer(ctx context.Context, options ...WriterOption) (io.WriteCloser, func() error, error)
Writer returns a writer for the run's stream, for step context and for use outside a run. It waits until no other writer holds the stream name. Close closes the stream for all writers, while the returned release function only gives up this writer's hold so another writer can continue the stream. Writer returns ErrNotInStep in workflow context.
type StartOnLatest ¶ added in v0.7.0
type StartOnLatest struct{}
StartOnLatest marks a workflow, when embedded in the workflow struct, whose new runs start on the World's latest deployment instead of the deployment that starts them:
type CheckIns struct {
workflow.Struct[CheckInsResult]
workflow.StartOnLatest
UserID string
}
A run never moves once started, so its event log is only ever replayed by the code that wrote it. A workflow that starts its next run before it finishes, such as a daily chain, moves to new code at that boundary instead of staying on the deployment its first run started on until the deployment is deleted. Mark only workflows nothing waits on the output of, since a newer deployment may return a different output. On Worlds without deployment affinity, or that do not implement worlds.LatestDeployments, it changes nothing.
It has no fields, so it adds nothing to the workflow's JSON input.
type StepMetadata ¶
type StepMetadata struct {
// ID is the step ID, stable across attempts. It is suitable as an
// idempotency key.
ID string
// Name is the step function's name.
Name string
// StartedAt is when the current attempt started.
StartedAt time.Time
// Attempt is the current attempt number, starting at 1.
Attempt int
}
StepMetadata describes the step attempt that step context belongs to.
func GetStepMetadata ¶
func GetStepMetadata(ctx context.Context) StepMetadata
GetStepMetadata returns metadata about the step ctx belongs to, or the zero StepMetadata when ctx does not belong to a step.
type StepOptions ¶
type StepOptions struct {
// MaxRetries is the number of times a failed step is retried before it
// fails. Omitting StepOptions allows 3 retries, while the zero value
// allows none. A FatalError is never retried.
MaxRetries int
}
StepOptions holds the options for a step.
type StreamChunk ¶
type StreamChunk = worlds.StreamChunk
StreamChunk is one chunk of a stream: the data of one write and its zero-based index in the stream.
type StreamReader ¶
type StreamReader interface {
// Read reads the stream's bytes, blocking until data is written. It
// returns io.EOF once the stream is closed and read.
io.Reader
// Next returns the next chunk, blocking until one is written. After a
// partial Read, it returns the rest of the current chunk. It returns
// io.EOF once the stream is closed and read.
Next() (StreamChunk, error)
// TailIndex returns the index of the stream's last chunk, or -1 when it
// has none. A reconnecting client can resume from the index after the
// last chunk it received.
TailIndex() (int, error)
}
StreamReader reads a run's stream. Read joins the stream's chunks into bytes, while Next returns one chunk at a time with its index, so a reader can relay whole writes and resume after the last index it saw.
func Reader ¶
func Reader(ctx context.Context, options ...ReaderOption) (StreamReader, error)
Reader returns a reader for a stream of the run ctx belongs to, from ReaderOption.StartIndex. Reads block until data is written and return io.EOF once the stream is closed. It must be called in step context. It returns ErrNotInStep in workflow context and ErrNoWorkflow outside a run.
type Struct ¶ added in v0.3.0
type Struct[Out any] struct{}
Struct declares a workflow's output type when embedded in the workflow struct, in place of writing its Workflow(Out) method:
type GenerateReport struct {
workflow.Struct[GenerateReportResult]
Topic string
}
It has no fields, so it adds nothing to the workflow's JSON input.
type WaitGroup ¶
type WaitGroup struct {
// contains filtered or unexported fields
}
WaitGroup waits for all its members, ignoring operation failures. Its zero value is ready to use. After completion, new work is ignored. Create a new WaitGroup to wait for more work.
type WakeOptions ¶
type WakeOptions struct {
// CorrelationIDs limits WakeUp to the waits with these IDs. When empty,
// WakeUp settles every pending wait in the run.
CorrelationIDs []string
}
WakeOptions holds the options to WakeUp.
type Webhook ¶
type Webhook[T any] struct { // contains filtered or unexported fields }
Webhook is a hook resumed by an HTTP request to its URL, whose JSON request body is decoded as T.
func CreateWebhook ¶
CreateWebhook creates a webhook in the run ctx belongs to. A webhook is a hook resumed once by an HTTP request to its URL. On replay it returns the same webhook. The last of options applies. It returns ErrNoWorkflow when ctx does not belong to a run.
func (*Webhook[T]) Dispose ¶
Dispose durably deactivates the webhook endpoint and panics on failure.
func (*Webhook[T]) Request ¶
func (w *Webhook[T]) Request(ctx context.Context) (*WebhookRequest[T], error)
Request waits for the HTTP request and preserves its origin for a step response.
type WebhookOption ¶
type WebhookOption struct {
// Method is the HTTP method the webhook accepts. When empty, it accepts
// any method.
Method string
// Response is the response sent to the request that resumes the webhook.
// Its body is limited to 128 KiB. When nil and Manual is false, the
// request receives 202 Accepted.
Response *http.Response
// Manual holds the request open until the runner responds with
// RespondWith.
Manual bool
}
WebhookOption holds the options to CreateWebhook. A webhook always gets a random hook token, since its URL is public.
type WebhookRequest ¶
WebhookRequest is a serializable HTTP request. Pass it to a step to inspect its body or send a manual response.
func (*WebhookRequest[T]) JSON ¶
func (r *WebhookRequest[T]) JSON() (T, error)
JSON decodes the stored body without consuming Request.Body.
func (*WebhookRequest[T]) MarshalJSON ¶
func (r *WebhookRequest[T]) MarshalJSON() ([]byte, error)
func (*WebhookRequest[T]) RespondWith ¶
RespondWith records the response for this request. It is step-only, and retrying the same response is idempotent.
func (*WebhookRequest[T]) UnmarshalJSON ¶
func (r *WebhookRequest[T]) UnmarshalJSON(data []byte) error
type WorkflowMetadata ¶
type WorkflowMetadata struct {
// Name is the workflow name.
Name string
// RunID is the run's ID.
RunID string
// StartedAt is when the run started, or when it was created if it has
// not started.
StartedAt time.Time
}
WorkflowMetadata describes the run a workflow or step is executing in.
func GetWorkflowMetadata ¶
func GetWorkflowMetadata(ctx context.Context) WorkflowMetadata
GetWorkflowMetadata returns metadata about the run ctx belongs to, or the zero WorkflowMetadata when ctx does not belong to a run.
type World ¶
World is the backend a run is recorded in. It provides storage, a delivery queue, and streams.
type WriterOption ¶
type WriterOption struct {
// Name is the stream name. The zero value names the run's default stream.
Name string
}
WriterOption holds the options to Writer and Run.Writer.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package check provides Analyzer, a static analyzer that reports runners that cannot replay deterministically and calls that misuse the workflow API.
|
Package check provides Analyzer, a static analyzer that reports runners that cannot replay deterministically and calls that misuse the workflow API. |
|
cmd
|
|
|
workflowcheck
command
Command workflowcheck runs the check analyzer as a go vet tool.
|
Command workflowcheck runs the check analyzer as a go vet tool. |
|
Package workflowai runs AI agents as durable workflow runs.
|
Package workflowai runs AI agents as durable workflow runs. |
|
Package workflowdev integrates go-workflow's static analyzer with go-dev.
|
Package workflowdev integrates go-workflow's static analyzer with go-dev. |
|
Package workflowtest provides conformance tests for worlds.World implementations.
|
Package workflowtest provides conformance tests for worlds.World implementations. |
|
Package worlds defines the World contract that go-workflow records runs in, the runtime that executes deliveries against it, and the HTTP server that exposes a World to clients.
|
Package worlds defines the World contract that go-workflow records runs in, the runtime that executes deliveries against it, and the HTTP server that exposes a World to clients. |
|
aws
Package awsworld implements a World on DynamoDB, SQS, and EventBridge Scheduler, for deployments on AWS Lambda or other AWS compute where any number of functions and processes share one table.
|
Package awsworld implements a World on DynamoDB, SQS, and EventBridge Scheduler, for deployments on AWS Lambda or other AWS compute where any number of functions and processes share one table. |
|
local
Package localworld implements a World on JSON files in a local directory, for development and single-process deployments.
|
Package localworld implements a World on JSON files in a local directory, for development and single-process deployments. |
|
postgres
Package postgresworld implements a World on PostgreSQL, for production deployments where any number of application and worker processes share one database.
|
Package postgresworld implements a World on PostgreSQL, for production deployments where any number of application and worker processes share one database. |
|
testworld
Package testworld implements a World in memory, for tests.
|
Package testworld implements a World in memory, for tests. |
|
vercel
Package vercelworld implements a World on Redis (over TCP or the Upstash REST API) and Vercel Queues, for deployments on Vercel Functions.
|
Package vercelworld implements a World on Redis (over TCP or the Upstash REST API) and Vercel Queues, for deployments on Vercel Functions. |