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

temporalworkflow

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: MIT Imports: 15 Imported by: 0

README

Temporal Workflow

arkoren.dev/driver/temporal/temporalworkflow runs the Arkoren workflow facade on Temporal. Each facade workflow is a Temporal workflow, each step an activity.

Install with go get arkoren.dev/driver/temporal. The examples import "arkoren.dev/core/service/workflow", "arkoren.dev/driver/temporal", and "arkoren.dev/driver/temporal/temporalworkflow". For a standalone Compose file, host configuration, and cluster-health check, see running Temporal locally.

Given the onboarding workflow and step, register a worker before starting your existing app. This address matches the module's local Compose server:

err := app.Run(ctx, func(compose *application.Composer) {
	registry := compose.Must(workflow.Handlers(Onboard, SendWelcome))
	host := temporal.New(func(host *temporal.Builder) {
		host.HostPort("localhost:17233")
		host.TaskQueue("app")
	})
	compose.Cleanup(host.Stop)
	// Worker: register workflows and activities before host.Start.
	runner := compose.Must(temporalworkflow.NewRunner(host, registry))
	client := workflow.NewClient(runner.Driver())
	// Pass client to your application services here.
	_ = client
	compose.Startup(host.Start)
})

Import application from arkoren.dev/core/application. Composition completes before startup; cleanup is registered before runner validation can fail.

After the application starts the host, use client.Start(ctx, Onboard, "user-42", user) to submit your User payload.

A process that only starts and controls runs needs no worker. Use this alternative in its composition callback, with the same registry:

err := app.Run(ctx, func(compose *application.Composer) {
	host := temporal.New(func(host *temporal.Builder) {
		host.HostPort("localhost:17233")
		host.TaskQueue("app")
		host.NoWorker(true)
	})
	compose.Cleanup(host.Stop)
	driver := compose.Must(temporalworkflow.NewDriver(host, func(driver *temporalworkflow.DriverBuilder) {
		driver.Registry(registry)
	}))
	client := workflow.NewClient(driver)
	// Pass client to your application services here.
	_ = client
	compose.Startup(host.Start)
})

Execution and handle safety

Use the same prefix (Prefix, default arkoren) and task queue in both processes. Registry lets the driver set the Temporal execution timeout from MaxDuration plus Delay as a backstop; the runner always enforces MaxDuration with a timer inside the workflow. NewRunner on a NoWorker(true) host is an error. Never block on ctx.Done() in a workflow function; poll it.

Results, statuses, cancellation, and signals verify the native workflow type before using a named handle. A wrong workflow name returns workflow.ErrNotFound without reading output or issuing the command. Native clients therefore need description permission as well as command permission. These checks do not replace application authorization, and IDs remain unique across the namespace.

An explicit step Timeout(0) removes the attempt timeout; the workflow's MaxDuration remains the upper bound. Retry Max caps the first retry as well as later retries; Max zero does not inherit Temporal's implicit 100-times-initial cap. Backend duration limits still apply: the requested largest Go duration can be reduced by the server, so this is not full Go-duration portability or a universal uncapped duration guarantee. The integration-tested two-attempt policy on server 1.29.1 retained 876000h (100 times 365 days), rather than the requested largest Go duration. Check your server's version and persisted policy instead of assuming that bound universally.

A completed step policy with multiple attempts and Initial zero returns workflow.ErrUnsupported before encoding or scheduling the activity, even if the handler would have succeeded on its first attempt. No approximate positive delay is inserted. Single-attempt policies remain supported because backoff is unused; Step.Derive determines the local policy independently of registration. Ordinary defaults are unchanged: one attempt, and positive one-second initial backoff when Retry enables further attempts. Whole-workflow execution retries remain disabled; step retry counts stay explicitly finite.

Child-result and Spawn-acknowledgement waits end when the parent is canceled or reaches MaxDuration, independently of native future completion. Spawn still uses detached child ownership: an error while waiting does not prove the child never started. Child acquires cancellation ownership only when Temporal atomically creates the native child. A duplicate start joins through a result-reading activity, ignores the replacement input, and acquires no ownership. Canceling or timing out that parent ends only its wait; the original run retains its owner and can still finish through a signal. Newly created children still stop with their parent, using native cancellation or parent-close termination. This ownership clarification adds no history command or replay marker and preserves the existing child/join command sequence. Workflow logging resolves bound and grouped slog.LogValuer values before forwarding them to the native logger, so native formatting cannot bypass their redaction.

Existing histories require a rollout decision

Older workers silently mapped zero initial delay to a positive interval. Rejecting that step now changes its native command sequence. Keep affected executions routed to legacy workers until they finish, or drain them before deploying this change. The driver adds no native version marker and does not use IsReplaying to bypass rejection. Mixing old and new workers on the same unversioned task queue does not provide that routing guarantee.

If you intentionally want the previous observed behavior, configure its positive initial interval explicitly, including local derived definitions. The previous fallback was one second before applying Max. Replay representative retained histories before deployment; a matching-policy replay fixture is not proof that every application history is compatible. Applications needing truly immediate retries can choose a compatible driver or explicitly design a bounded workflow loop of single-attempt steps; that changes history and requires its own rollout.

Native ownership and shutdown

NoWorker defaults to false; a later false restores worker permission without forcing an empty worker. NewFrom borrows the SDK client and applies TaskQueue, WorkerOptions, WorkerStopTimeout, and NoWorker. Configure logging on the supplied native client: NewFrom ignores the host Logger setting. Stop leaves that client open. A nonzero native worker stop timeout wins over the host timeout. SDK option records are copied by value, not recursively.

Call host.Stop after host.Start has returned. Stop initiates cleanup even with an expired context; its context bounds waiting for native worker cleanup, not arbitrary callback execution. An owned client is released after native worker cleanup completes, possibly after Stop returns. The native worker timeout is a grace wait, not a total shutdown budget: SDK hooks must return, and activity code must observe context cancellation. A canceled startup releases acquired resources, but native worker startup itself has no context and must return first.

Contributor verification

Contributor integration setup: docker compose up -d --wait in driver/temporal starts the temporal dev server of its compose.yaml on 127.0.0.1:17233. See the package documentation for the semantics of MaxDuration, cancellation, signals, and children. TestIntegrationServerVersionAndRetryMaximum observes the server version through the public native SDK and records its server-persisted activity retry maximum; the image tag alone is not version evidence.

Construction callbacks

Construction callbacks run synchronously once, in order, on one fresh draft. Each setting returns that same draft. Omitted callbacks and expanded nil or empty slices leave defaults unchanged; a supplied nil callback panics. Publication detaches owned settings, not clients, services, SDK internals, or function captures. Use DriverBuilder with NewDriver and RunnerBuilder with NewRunner. Only DriverBuilder has Registry; the required NewRunner registry supplies its driver registry.

Documentation

Overview

Package temporalworkflow implements workflow.Driver on Temporal workflows and activities.

Two types split the work. NewRunner runs in the worker process: it registers the workflows and steps of a workflow.Registry on a [temporal.Host]. NewDriver runs in any process that starts and controls runs: it uses only the client of the host, so the host can be client-only with [temporal.Builder.NoWorker].

Construction uses DriverBuilder or RunnerBuilder, separately from workflow declarations and host construction. Policies run once in order on one fresh draft; nil entries panic and expanded nil or empty slices omit edits. Only DriverBuilder exposes Registry; NewRunner's required registry supplies its driver registry. Published settings detach from retained drafts, not services.

driver, err := temporalworkflow.NewDriver(temporal.New(), func(driver *temporalworkflow.DriverBuilder) {
	driver.Prefix("orders")
})
if err != nil {
	panic(err)
}
_ = workflow.NewClient(driver)

Names

The workflow "onboard" with the default prefix is the Temporal workflow type "arkoren-wf-onboard", the step "send-welcome" is the activity type "arkoren-step-send-welcome", and the signal "email-confirmed" is the signal "arkoren.sig.email-confirmed". The workflow ID is the run id of the facade. Payloads are the JSON of the facade as raw JSON values, so the Temporal UI shows them as they are.

Semantics

  • Start: conflict policy FAIL and reuse policy REJECT_DUPLICATE, so a second Start with the same id is workflow.ErrAlreadyStarted, also after the run ended. Delay is the Temporal start delay and Metadata is the memo. With DriverBuilder.Registry (the driver of a Runner has it) the execution timeout is MaxDuration plus Delay and an unregistered name is workflow.ErrNotFound.
  • MaxDuration: the runner starts a timer when the workflow starts; when it fires, the context of the run is canceled, blocking calls return an error that matches workflow.ErrTimeout, and the run fails with that error. The server execution timeout (MaxDuration plus Delay, set when the driver knows the registry) is only a backstop for a stuck run; it ends the run as timed out, which is also workflow.ErrTimeout and workflow.Failed.
  • Cancel: CancelWorkflow. The context of the run is canceled, so Sleep, Wait, Select, Step, and Child return workflow.ErrCanceled and the run ends as Canceled; Result is workflow.ErrCanceled and Status is workflow.Canceled. The driver describes the named execution before observations and commands; a wrong workflow name is workflow.ErrNotFound and never issues a cancel or signal. Finished known runs cancel without error. Native clients need description permission in addition to command permissions. These are typed-handle checks, not application authorization.
  • Signal: SignalWorkflow, which buffers the value until the workflow reads it. An unknown or finished run is workflow.ErrNotFound. The facade keeps the first value per signal; later values stay unread.
  • Status: Running, and ContinuedAsNew, are workflow.Running; Completed is workflow.Completed; Failed, TimedOut, and Terminated are workflow.Failed; Canceled is workflow.Canceled. Result of a terminated run is an error of kind "temporal.terminated".
  • Failures: a failing workflow or step ends with an application error of type "arkoren.error" whose detail is the workflow.EncodeError envelope, so error kinds survive. A workflow.Permanent failure is a non-retryable application error.
  • Steps run as activities with a start-to-close timeout of Timeout and a Temporal retry policy built from Attempts, Initial, Factor, and Max. Per-call options override them. Timeout zero removes the attempt limit; the workflow MaxDuration supplies the required native schedule-to-close bound instead. A timeout is workflow.ErrTimeout. A positive Max caps even the first retry interval; zero Max requests Go's largest duration rather than Temporal's implicit 100-times-initial cap. Backend duration limits can reduce that request: full Go-duration portability is not promised. Multiple attempts with Initial zero return workflow.ErrUnsupported before activity encoding or scheduling; no approximate positive delay is inserted. A single attempt remains supported because backoff is unused. The completed local Step.Derive policy is authoritative, not the registered default.
  • Child runs a child workflow with the execution timeout of its MaxDuration and waits. Parent cancellation requests cancellation of an owned native child, but ends the runtime wait without requiring child callbacks to stop. The child id is joined when a run with it exists: a workflow cannot join a run, so the runner waits for it in an activity ("<prefix>-join") that reads the result through the client; the run must use the same task queue and the activity is retried at most three times. Spawn starts the child with the parent close policy ABANDON on a context that is disconnected from the parent, and waits only until the child started. Canceling observation of an already existing run does not cancel that run. Spawn's acknowledgement wait still ends on parent cancellation or MaxDuration; the detached child might have started even when that wait returns an error. Creation versus joining is decided by Temporal's atomic child-start acknowledgement, not a status lookup. Only newly created children have parent-close policy TERMINATE; an existing run retains its original owner, including after parent MaxDuration. This clarification adds no history command or marker and does not change the existing child/join sequence.
  • Wait and Select use a Temporal selector over the signal channels, the cancellation of the run, and timers. Timers that lose are canceled and signals that no case consumed stay buffered.
  • Now is the workflow time, UUID is derived from the run ID of the execution and a counter (no history event), and Logger writes to the Temporal workflow logger, which is silent while the workflow replays. LogValuers, including nested groups and bound attributes, are resolved before crossing into native logging so slog redaction applies. Raw returns the go.temporal.io/sdk/workflow.Context of the run.
  • Done and Err: Err reads the Temporal context, so it is deterministic and accurate as soon as the cancellation was delivered. Done is a native channel that is closed when a runtime call or Err sees the context done, or when a coroutine of the runtime that waits on the Temporal channel is scheduled. Poll it with a non-blocking select; do not block on it with "<-ctx.Done()": Temporal cannot schedule a native block and fails the workflow task as a deadlock. Use Sleep, Wait, or Select to block.
  • Retention is a setting of the Temporal namespace and is ignored, like Description.

Retry-policy compatibility and rollout

Core step defaults remain supported: one attempt, or a positive one-second initial delay when Retry enables more attempts. Whole-workflow execution retry policy remains absent; finite application step retries are native activity retries. Omitting an activity retry policy would enable native server defaults, including potentially unlimited attempts, so this driver never uses omission to disable application retries.

The previous driver silently replaced zero Initial with a positive native interval. Rejecting that policy changes command selection and is not safe as an unqualified in-place worker upgrade for existing zero-policy histories. Keep those executions on legacy workers using application-owned worker routing until they finish, or drain them before upgrading. Explicitly choosing the old positive interval can preserve equivalent histories; replay your actual histories before deployment. The driver adds no version marker and does not use IsReplaying to suppress policy rejection.

Max zero avoids the native implicit 100-times-initial cap, not every backend duration bound. Native server versions can cap requested durations. Inspect actual server version and effective policy when engine limits matter; do not infer the server version from a CLI image tag or assume a universal maximum. The integration-tested two-attempt policy on server 1.29.1 retained 876000 hours (100 times 365 days), rather than the requested largest Go duration. This is evidence for that server and policy, not a duration guarantee for every backend.

Telemetry

Configure workflow.RegistryBuilder.Telemetry in the worker registry, separate from workflow.ClientBuilder.Telemetry in each client process. StartOptions.Trace travels in a dedicated argument envelope, never memo. Replay forwards it as deterministic data through activities and child/spawn runs; real activities extract it before invoking the registered step. Signals keep the start parent. No host propagator hook is needed. Deploy upgraded workers before enabling traced producers; old workers cannot decode traced envelopes. Legacy untraced histories retain their argument shape. Export every pod to a common backend; client Result observations measure waiting, not durable run duration.

Caveats

  • NewRunner fails on a host built with [temporal.Builder.NoWorker]. A process that sets Builder.NoWorker is client-only and uses NewDriver; a runner on such a host would never run a workflow.
  • Temporal ends a blocked workflow coroutine with runtime.Goexit, which recover does not catch, so the panic recovery of the facade does not swallow it. The runner needs no special handling. A panic in workflow code becomes a workflow failure, like in the other drivers, and not a retried workflow task.
  • The workflow function replays, so it must be deterministic. Do not start goroutines that call the context.
  • The runner and the drivers that talk to it must use the same prefix and the same codec in workflow.HandlersWith and workflow.ClientBuilder.Codec.
  • Workflow IDs are unique per namespace, so the same run id of two different workflows collides.
  • A step that fails makes the Temporal worker log an error line for every attempt.

Index

Constants

View Source
const DefaultPrefix = "arkoren"

DefaultPrefix is the name prefix used when DriverBuilder.Prefix is empty.

Example:

component, err := NewDriver(temporal.New(), func(driver *DriverBuilder) {
	driver.Prefix(DefaultPrefix)
})
if err != nil {
	panic(err)
}
_ = component

Variables

This section is empty.

Functions

This section is empty.

Types

type Driver

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

Driver is a workflow.Driver that starts and controls runs through the Temporal client of a host. It runs no workflow code; the Runner of the worker process does. A Driver is safe for concurrent use. Typed observations and commands verify the persisted native workflow type; namespace-wide ID uniqueness does not permit a wrong-name handle to use it.

Example:

driver, err := NewDriver(temporalhost.New())
if err != nil {
	return err
}
_ = workflow.NewClient(driver)

func NewDriver

func NewDriver(host *temporalhost.Host, configure ...DriverBuilderFunc) (*Driver, error)

NewDriver returns a Driver that talks to Temporal through host. The host needs no worker for that; use temporalhost.Builder.NoWorker in a process that only starts runs. Call it before or after host.Start; calls fail until the host has a native client. A NewFrom client is available immediately, whereas a dialing host acquires its client during Start. It performs no I/O. Callbacks run once in order on one fresh DriverBuilder; nil entries panic. Published settings are independent of a retained draft. DriverBuilder.Registry optionally supplies timeout and registration knowledge to a client-only driver.

Example:

driver, err := NewDriver(temporalhost.New(), func(driver *DriverBuilder) {
	driver.Prefix("orders")
})
if err != nil {
	panic(err)
}
_ = driver

func (*Driver) Cancel

func (driver *Driver) Cancel(ctx context.Context, name, id string) error

Cancel verifies the named native run before requesting cancellation. A finished known run is not an error, including when it finishes between the description and cancellation request. Unknown IDs or mismatched workflow names return workflow.ErrNotFound without issuing a cancellation request.

Example:

if err := driver.Cancel(ctx, "onboard", "user-42"); err != nil {
	return err
}

func (*Driver) Result

func (driver *Driver) Result(ctx context.Context, name, id string) ([]byte, error)

Result waits for the run to end. A canceled run gives workflow.ErrCanceled, a run that hit its execution timeout gives workflow.ErrTimeout, and other failures are decoded from the error envelope the Runner stored. A wrong workflow name returns ErrNotFound before reading output; a native timeout outranks its last application-failure cause.

Example:

output, err := driver.Result(ctx, "onboard", "user-42")
if err != nil {
	return err
}
_ = output // Encoded facade output, not a native Temporal payload wrapper.

func (*Driver) Signal

func (driver *Driver) Signal(ctx context.Context, name, id, signal string, v []byte) error

Signal sends the signal to the run. It returns workflow.ErrNotFound for an unknown or finished run. Temporal buffers a signal until the workflow reads it. A mismatched workflow name is rejected before delivery; description and command permissions are both required on the native client.

Example:

if err := driver.Signal(ctx, "onboard", "user-42", "approved", []byte(`{"v":true}`)); err != nil {
	return err
}

func (*Driver) Start

func (driver *Driver) Start(ctx context.Context, name, id string, in []byte, options workflow.StartOptions) error

Start starts run id of the workflow called name with a workflow ID of id. It returns workflow.ErrAlreadyStarted when Temporal knows a run with this ID, also a finished one, and workflow.ErrNotFound when the configured registry lacks the workflow. StartOptions.Delay is the Temporal start delay and StartOptions.Metadata becomes the memo.

Example:

err := driver.Start(ctx, "onboard", "user-42", []byte(`{"v":"Ada"}`), workflow.StartOptions{})
if err != nil && !errors.Is(err, workflow.ErrAlreadyStarted) {
	return err
}

func (*Driver) Status

func (driver *Driver) Status(ctx context.Context, name, id string) (workflow.Status, error)

Status describes the run. Completed, failed, timed out, and terminated runs map to workflow.Completed or workflow.Failed, a canceled run to workflow.Canceled, and a run that continued as new to workflow.Running. Missing IDs and mismatched workflow names return ErrNotFound.

Example:

status, err := driver.Status(ctx, "onboard", "user-42")
if err != nil {
	return err
}
_ = status == workflow.Running

type DriverBuilder

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

DriverBuilder edits the construction settings of NewDriver. Callbacks share one fresh draft and run once in order; a nil callback panics. Retaining a draft does not permit changes to the published component. Dependencies and native SDK internals retain their existing ownership.

Example:

component, err := NewDriver(temporal.New(), func(driver *DriverBuilder) {
	driver.Logger(slog.Default())
})
if err != nil {
	panic(err)
}
_ = component

func (*DriverBuilder) Logger

func (driver *DriverBuilder) Logger(logger *slog.Logger) *DriverBuilder

Logger receives log lines of the driver. Nil uses slog.Default. It returns the same draft for subsequent settings.

Example:

component, err := NewDriver(temporal.New(), func(driver *DriverBuilder) {
	driver.Logger(slog.Default())
})
if err != nil {
	panic(err)
}
_ = component

func (*DriverBuilder) Prefix

func (driver *DriverBuilder) Prefix(prefix string) *DriverBuilder

Prefix names the Temporal workflow types ("<prefix>-wf-<name>"), the activity types ("<prefix>-step-<name>"), and the signals ("<prefix>.sig.<name>"). Empty uses DefaultPrefix. A runner and the drivers that talk to it must use the same prefix. It returns the same draft for subsequent settings.

Example:

component, err := NewDriver(temporal.New(), func(driver *DriverBuilder) {
	driver.Prefix("example")
})
if err != nil {
	panic(err)
}
_ = component

func (*DriverBuilder) Registry

func (driver *DriverBuilder) Registry(registry *workflow.Registry) *DriverBuilder

Registry lets a Driver know the workflows: it sets the Temporal execution timeout from MaxDuration and returns workflow.ErrNotFound for an unregistered name. A Runner fills it in for its own driver. Without it the run has no server-side execution timeout; the runner still enforces MaxDuration inside the workflow. It returns the same draft for subsequent settings.

Example:

component, err := NewDriver(temporal.New(), func(driver *DriverBuilder) {
	driver.Registry(nil)
})
if err != nil {
	panic(err)
}
_ = component

type DriverBuilderFunc

type DriverBuilderFunc = func(*DriverBuilder)

DriverBuilderFunc configures a fresh client-driver draft during NewDriver. Callbacks run once synchronously in order; nil entries panic. Native host and registry dependencies remain shared after settings publication.

Example:

policies := []DriverBuilderFunc{
	func(driver *DriverBuilder) {
		driver.Prefix("orders")
	},
}
driver, err := NewDriver(temporal.New(), policies...)
if err != nil {
	return err
}
_ = workflow.NewClient(driver)

type Runner

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

Runner serves the workflows and steps of a workflow.Registry on the worker of a temporal.Host (package arkoren.dev/driver/temporal). Create it with NewRunner before the host starts. It shares the registry's handlers and native host; it does not own that host's lifecycle. Workflow functions replay and must remain deterministic.

Example:

registry, err := workflow.Handlers()
if err != nil {
	return err
}
runner, err := NewRunner(temporalhost.New(), registry)
if err != nil {
	return err
}
_ = workflow.NewClient(runner.Driver())

func NewRunner

func NewRunner(host *temporalhost.Host, registry *workflow.Registry, configure ...RunnerBuilderFunc) (*Runner, error)

NewRunner registers every workflow of registry as the Temporal workflow "<prefix>-wf-<name>" and every step as the activity "<prefix>-step-<name>" on host. It returns temporalhost.ErrStarted when host is already started. The workflows run on the task queue of the host.

Cancellation, MaxDuration, and step retries follow the rules in the package documentation. Callbacks run once in order on one fresh RunnerBuilder; nil entries panic. The required registry always supplies the runner's driver registry; the runner draft has no Registry setting. Nil hosts and registries remain errors.

Example:

registry, err := workflow.Handlers()
if err != nil {
	panic(err)
}
runner, err := NewRunner(temporalhost.New(), registry, func(runner *RunnerBuilder) {
	runner.Prefix("orders")
})
if err != nil {
	panic(err)
}
_ = runner.Driver()

func (*Runner) Driver

func (runner *Runner) Driver() *Driver

Driver returns the workflow.Driver of the runner. It starts runs on the same host and sees the workflows of the registry. The returned pointer is shared and safe for concurrent command use; this transfers no host ownership.

Example:

runner, err := NewRunner(host, registry)
if err != nil {
	return err
}
client := workflow.NewClient(runner.Driver())
_ = client

type RunnerBuilder

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

RunnerBuilder edits the construction settings of NewRunner. Callbacks share one fresh draft and run once in order; a nil callback panics. Retaining a draft does not permit changes to the published component. Dependencies and native SDK internals retain their existing ownership.

Example:

registry, err := workflow.Handlers()
if err != nil {
	panic(err)
}
component, err := NewRunner(temporal.New(), registry, func(runner *RunnerBuilder) {
	runner.Logger(slog.Default())
})
if err != nil {
	panic(err)
}
_ = component

func (*RunnerBuilder) Logger

func (runner *RunnerBuilder) Logger(logger *slog.Logger) *RunnerBuilder

Logger receives log lines of the driver. Nil uses slog.Default. It returns the same draft for subsequent settings.

Example:

registry, err := workflow.Handlers()
if err != nil {
	panic(err)
}
component, err := NewRunner(temporal.New(), registry, func(runner *RunnerBuilder) {
	runner.Logger(slog.Default())
})
if err != nil {
	panic(err)
}
_ = component

func (*RunnerBuilder) Prefix

func (runner *RunnerBuilder) Prefix(prefix string) *RunnerBuilder

Prefix names the Temporal workflow types ("<prefix>-wf-<name>"), the activity types ("<prefix>-step-<name>"), and the signals ("<prefix>.sig.<name>"). Empty uses DefaultPrefix. A runner and the drivers that talk to it must use the same prefix. It returns the same draft for subsequent settings.

Example:

registry, err := workflow.Handlers()
if err != nil {
	panic(err)
}
component, err := NewRunner(temporal.New(), registry, func(runner *RunnerBuilder) {
	runner.Prefix("example")
})
if err != nil {
	panic(err)
}
_ = component

type RunnerBuilderFunc

type RunnerBuilderFunc = func(*RunnerBuilder)

RunnerBuilderFunc configures a fresh worker-runner draft during NewRunner. Callbacks run once synchronously in order; nil entries panic. The positional registry is authoritative for both runner execution and its client driver.

Example:

policies := []RunnerBuilderFunc{
	func(runner *RunnerBuilder) {
		runner.Prefix("orders")
	},
}
registry, err := workflow.Handlers()
if err != nil {
	return err
}
runner, err := NewRunner(temporal.New(), registry, policies...)
if err != nil {
	return err
}
_ = runner.Driver()

Directories

Path Synopsis
internal
execution
Package execution owns deterministic Temporal workflow execution.
Package execution owns deterministic Temporal workflow execution.
protocol
Package protocol owns Temporal raw JSON and native failure envelopes.
Package protocol owns Temporal raw JSON and native failure envelopes.

Jump to

Keyboard shortcuts

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