Skip to content

Starting and Reading Runs ​

Clients ​

Code outside a run uses a Client to start, read, cancel, and resume runs. The workflow package functions find the Client in the context.

ConstructorUse when
workflow.NewClient(world)The World is open in the same process.
workflow.NewHTTPClient(endpoint)The World is served by its HTTP handler in another process.

Put a Client in a context with workflow.NewContext, or in every request context of an HTTP server with workflow.Middleware:

go
ctx = workflow.NewContext(ctx, workflow.NewClient(world))
go
client := workflow.NewHTTPClient("http://workflow-worker:8081/v1/workflow")
log.Fatal(http.ListenAndServe(":8080", workflow.Middleware(mux, client)))

NewHTTPClient takes an absolute URL and panics on anything else. It uses http.DefaultClient unless you pass your own *http.Client, for example one that adds authentication:

go
client := workflow.NewHTTPClient(endpoint, &http.Client{Transport: authTransport})

The endpoint is the URL prefix the World's handler serves, including /v1/workflow. The client posts to <endpoint>/rpc, so for a worker serving HTTP(world) at the root of port 8081, the endpoint is http://workflow-worker:8081/v1/workflow.

Starting a run ​

workflow.Start starts a run of a workflow and returns a handle without waiting. It needs only the workflow type.

go
run, err := workflow.Start(ctx, workflows.GenerateReport{Topic: "workflows"})
if err != nil {
	return err
}

fmt.Println(run.ID())

It returns workflow.ErrNoClient when the context has no Client and does not belong to a run. In workflow context, Start starts a child run.

Getting an existing run ​

workflow.Get returns a handle to a run by ID. The type parameter is the workflow's output type. Get does not check that the run exists. Call run.Exists to check it.

go
run, err := workflow.Get[workflows.GenerateReportResult](ctx, runID)

The Run handle ​

MethodDescription
IDRun ID.
ValueOutput once the run finishes. Blocks outside workflow context until it finishes or ctx is done.
StatusCurrent Status.
ExistsWhether the run is recorded in its World.
WorkflowNameName of the workflow the run executes.
CancelCancels the run. No-op if it already finished.
WakeUpSettles pending timers early. See Sleep and Timers.
ReaderReads a stream from a chunk index. See Streams.
WriterWrites a stream from outside the run.

Value returns a failed run's error as a *workflow.Error and a cancelled run's as workflow.ErrRunCancelled. Status and WorkflowName return worlds.ErrRunNotFound for a missing run.

Statuses ​

StatusMeaning
workflow.StatusPendingRecorded but not started.
workflow.StatusRunningStarted and not finished.
workflow.StatusCompletedFinished with an output.
workflow.StatusFailedFinished with an error.
workflow.StatusCancelledCancelled before it finished.

Steps use the same statuses except for cancelled. A cancelled step records a fatal failure.

In workflow context ​

Inside a runner, methods that read or change the run use inline steps, and replay returns the recorded result. They never wait: Value returns workflow.ErrRunNotFinished for a run that hadn't finished. WakeUp records which waits it will wake in one inline step before waking them in another, so a retry never wakes a timer the other run created later. The exceptions are Reader and Writer, which are I/O and return workflow.ErrNotInStep there. Use them in a step.

Cancelling a run ​

Run.Cancel stops new work and leaves already-running steps to finish. Reading a cancelled run returns workflow.ErrRunCancelled. A managed context passed to Start does not control the run's lifetime. See Cancellation for examples and step cancellation behavior.

Resuming hooks ​

workflow.ResumeHook, ResumeHookWithRetries, and GetHook also use the Client in the context. See Hooks.

Lower-level access ​

workflow.Client is an alias of worlds.Client, which exposes the full API: listing runs and steps, setting attributes, reading streams by cursor, and analytics. See the worlds reference.

go
client := workflow.NewClient(world)
page, err := client.RunsList(ctx, worlds.RunsListInput{})

Released under the MIT License.