new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Temporal · Develop · all subjects

workers/basics

378 notes in this subject, read out of this brain and free to use. This is page 1 of 7.

TemporalWorker resource management

TemporalWorker implements IDisposable. Declare it with a using statement to ensure its resources are released when the process exits.

Register workflows and activities with worker

All workers polling the same task queue must register the same workflow types and activity types. Use AddWorkflow<T>() to register workflows and AddActivity() or AddAllActivities() to register activities. A worker that receives a task for a type it did not register will fail that task.

Graceful worker shutdown with CancellationToken

To stop a worker on demand, create a CancellationTokenSource, pass its Token to ExecuteAsync(), and cancel the source when the worker should stop, such as from a Console.CancelKeyPress handler. Set GracefulShutdownTimeout on TemporalWorkerOptions to control how long the worker waits for in-flight tasks to finish before stopping.

Create and run a TemporalWorker example

var options = new TemporalWorkerOptions("my-task-queue"); options.AddWorkflow<GreetingWorkflow>(); options.AddAllActivities(typeof(GreetingActivities), null); using var worker = new TemporalWorker(client, options); await worker.ExecuteAsync(CancellationToken.None); This example creates a worker that polls "my-task-queue", registers a workflow and activities, and polls indefinitely until process exit.

Graceful worker shutdown example

using var tokenSource = new CancellationTokenSource(); Console.CancelKeyPress += (_, eventArgs) => { tokenSource.Cancel(); eventArgs.Cancel = true; }; var options = new TemporalWorkerOptions("my-task-queue") { GracefulShutdownTimeout = TimeSpan.FromSeconds(30), }; options.AddWorkflow<GreetingWorkflow>(); using var worker = new TemporalWorker(client, options); await worker.ExecuteAsync(tokenSource.Token); This example sets up graceful shutdown with a 30-second timeout, allowing in-flight tasks to complete before the worker stops.

Create a TemporalWorker with task queue

Create a TemporalWorker by instantiating it with a TemporalClient and TemporalWorkerOptions that specifies the task queue name. Add workflows and activities to the worker options, then call ExecuteAsync() with a CancellationToken to start polling the task queue.

ExecuteAsync() polling behavior

ExecuteAsync() takes a CancellationToken and polls the task queue until the token is cancelled. Pass CancellationToken.None to poll indefinitely until the process exits. The method throws OperationCanceledException when the worker stops after cancellation.

TemporalWorkerOptions concurrency configuration

TemporalWorkerOptions controls concurrency limits, pollers, timeouts, and caching through parameters like MaxConcurrentActivities, MaxConcurrentWorkflowTasks, and MaxCachedWorkflows. The defaults work for most cases. For tuning, see Worker performance and worker tuning reference documentation.

.NET Serverless Workers supported providers

The .NET SDK supports AWS Lambda as a serverless compute provider. Use the Temporalio.Extensions.Aws.Lambda NuGet package to run a Worker as a Lambda function.

WorkerDeploymentVersion required for Lambda Workers

The WorkerDeploymentVersion is required for Lambda Workers. Worker Deployment Versioning is always enabled for Serverless Workers. Each Workflow must have a versioning behavior, either AutoUpgrade or Pinned. Set it per-Workflow with the [Workflow] attribute, or set a worker-level default with DefaultVersioningBehavior in DeploymentOptions. The default versioning behavior is AutoUpgrade.

Temporalio.Extensions.Aws.Lambda NuGet package

The Temporalio.Extensions.Aws.Lambda NuGet package lets you run a Temporal Serverless Worker on AWS Lambda. You deploy your Worker code as a Lambda function, and Temporal Cloud invokes it when Tasks arrive. Each invocation starts a Worker, polls for Tasks, then gracefully shuts down before a configurable invocation deadline. Install it with: dotnet add package Temporalio.Extensions.Aws.Lambda

Lambda workflow versioning behavior example

Example of setting versioning behavior on a Lambda workflow: [Workflow(VersioningBehavior = VersioningBehavior.Pinned)] public class SampleWorkflow with [WorkflowRun] public async Task<string> RunAsync(string name). This sets the versioning behavior to Pinned for this specific workflow.

Lambda worker handler creation example

Example of creating a Lambda handler: private static readonly Func<object?, ILambdaContext, Task> WorkerHandler = TemporalLambdaWorker.CreateHandler(new WorkerDeploymentVersion(LambdaWorkerSample.DeploymentName, LambdaWorkerSample.BuildId), Configure); public Task HandlerAsync(Stream input, ILambdaContext context) => WorkerHandler(input, context);

TLS/CA loading issues on Lambda

Some AWS Lambda .NET images override the SSL_CERT_FILE environment variable in a way that prevents the SDK's Rust-based runtime from loading system root CAs. If you encounter TLS certificate errors on Lambda, refer to the AWS Lambda .NET CA loading workaround in the SDK README.

TemporalLambdaWorker.CreateHandler usage

Use TemporalLambdaWorker.CreateHandler to create a Lambda handler that runs a Temporal Worker. Pass a WorkerDeploymentVersion and a configure callback that registers your Workflows and Activities. Assign the result to a static field so the handler is created once during Lambda cold start and reused across invocations.

Worker setup for standalone activities code example

package main import ( "github.com/temporalio/samples-go/standalone-activity/helloworld" "go.temporal.io/sdk/client" "go.temporal.io/sdk/contrib/envconfig" "go.temporal.io/sdk/worker" "log" ) func main() { c, err := client.Dial(envconfig.MustLoadDefaultClientOptions()) if err != nil { log.Fatalln("Unable to create client", err) } defer c.Close() w := worker.New(c, "standalone-activity-helloworld", worker.Options{}) w.RegisterActivity(helloworld.Activity) err = w.Run(worker.InterruptCh()) if err != nil { log.Fatalln("Unable to start worker", err) } } This example shows how to set up a Worker that processes standalone activities.

Namespace registration requires WorkflowExecutionRetentionPeriod

The Retention Period setting using WorkflowExecutionRetentionPeriod is mandatory when registering a Namespace. The minimum value you can set for this period is 1 day.

Update Namespace with Update API in Go

Use the Update API on the NamespaceClient to update Namespace configuration. Call client.Update(context.Background(), &workflowservice.UpdateNamespaceRequest{}) with the Namespace name and UpdateInfo containing fields like Description and OwnerEmail. You can also update Config for WorkflowExecutionRetentionTtl and BadBinaries, and ReplicationConfig for ActiveClusterName and Clusters.

Namespace registration takes up to 10 seconds

Namespace registration using the API takes up to 10 seconds to complete. You must wait for this registration to complete before starting the Workflow Execution against the Namespace.

List all Namespaces with ListNamespaces API in Go

Use the ListNamespaces API to return information and configuration details for all registered Namespaces on the Temporal Service. The request accepts PageSize and NextPageToken parameters. You can set a large PageSize or loop until NextPageToken is nil to retrieve all namespaces.

Register Namespace with NewNamespaceClient and Register API in Go

Use NewNamespaceClient with client.Options to create a NamespaceClient, then call the Register method with a RegisterNamespaceRequest containing the Namespace name and WorkflowExecutionRetentionPeriod. Example: client.NewNamespaceClient(client.Options{HostPort: ts.config.ServiceAddr}) followed by client.Register(ctx, &workflowservice.RegisterNamespaceRequest{Namespace: your-namespace-name, WorkflowExecutionRetentionPeriod: &retention})

Describe Namespace with DescribeNamespace API in Go

Use the DescribeNamespace API on the NamespaceClient to return information and configuration details for a registered Namespace. Example: client.NewNamespaceClient(client.Options{}).Describe(context.Background(), "default")

Go SDK quickstart and setup resources

The Temporal Go SDK quickstart is available at /develop/go/set-up-your-local-go. This includes detailed installation instructions and a walkthrough of how to use the core Temporal primitives (Activities, Workflows, and Workers) to build and run a Temporal application.

Go SDK Plugin system for custom integrations

The Temporal Go SDK provides a Plugin system that developers can use to build their own custom integrations beyond the pre-built integrations available for the SDK.

Pre-built integrations available for Go SDK

The Temporal Go SDK includes a set of pre-built integrations that are available for use. These integrations can be discovered through the IntegrationsGrid component which shows available integrations by SDK.

Go SDK platform documentation sections

The Go SDK platform documentation covers two main sections: Observability and Enriching the UI. These sections provide guidance on implementing platform-level features with the Go SDK.

Go SDK minimum version requirement

The Temporal Go SDK requires Go 1.18 or later. The official tutorials use Go 1.18 as the baseline version.

Install Temporal Go SDK with go get

Install the Temporal Go SDK by running 'go get go.temporal.io/sdk' and 'go get go.temporal.io/sdk/client' in your Go project, followed by 'go mod tidy' to resolve dependencies.

Client connection in Go

Create a Temporal client by calling client.Dial() with client.Options{}. The client is used to interact with the Temporal Service and should be closed with defer c.Close() when done.

Worker creation and configuration in Go

A Worker is created by calling worker.New() with a client, task queue name, and options. The Worker must register Workflows and Activities with RegisterWorkflow() and RegisterActivity(). The Worker is then started with w.Run(). Example: w := worker.New(c, "my-task-queue", worker.Options{}); w.RegisterWorkflow(greeting.SayHelloWorkflow); w.RegisterActivity(greeting.Greet); err = w.Run(worker.InterruptCh())

Workers documentation sections for Go SDK

The Workers section of the Go SDK documentation includes three main topics: running a Worker, Sessions, and Serverless Workers.

Enable Worker Versioning with BuildID option

To enable Worker Versioning for a Worker, set the BuildID field in worker.Options and set UseBuildIDForVersioning to true. Example: worker.Options{ BuildID: buildID, UseBuildIDForVersioning: true }.

Worker is a heavyweight object

The client and worker are heavyweight objects that should be created once per process.

Worker options configuration

Pass a worker.Options struct to worker.New() to configure concurrency limits, pollers, timeouts, and other Worker behavior. An empty struct uses defaults that work for most cases. For tuning these values against real load, see Worker performance and the Worker tuning reference documentation.

RegisterWorkflowWithOptions and RegisterActivityWithOptions

To customize the registered name or other options when registering Workflows or Activities, use RegisterWorkflowWithOptions() or RegisterActivityWithOptions(). These methods accept workflow.RegisterOptions and activity.RegisterOptions structures respectively.

Create a Worker with worker.New()

Create a Worker by calling worker.New() and passing three arguments: a Temporal Client, the name of the Task Queue to poll, and a worker.Options struct (which can be empty for defaults). Register your Workflow and Activity types using RegisterWorkflow() and RegisterActivity(), then call Run() to start polling. The Worker blocks while it polls.

Worker registration example

Example showing how to create and run a Worker in Go: package main import ( "log" "go.temporal.io/sdk/client" "go.temporal.io/sdk/contrib/envconfig" "go.temporal.io/sdk/worker" "github.com/temporalio/samples-go/helloworld" ) func main() { // The client and worker are heavyweight objects that should be created once per process. c, err := client.Dial(envconfig.MustLoadDefaultClientOptions()) if err != nil { log.Fatalln("Unable to create client", err) } defer c.Close() w := worker.New(c, "hello-world", worker.Options{}) w.RegisterWorkflow(helloworld.Workflow) w.RegisterActivity(helloworld.Activity) err = w.Run(worker.InterruptCh()) if err != nil { log.Fatalln("Unable to start worker", err) } } This example creates a Temporal Client, creates a Worker for the "hello-world" Task Queue, registers a Workflow and Activity, and runs the Worker with interrupt channel handling.

Worker.Run() with interrupt channel

Call Run() with worker.InterruptCh() so the Worker shuts down gracefully on SIGINT or SIGTERM. Alternatively, call Start() and Stop() separately for more control over the Worker lifecycle.

Register Workflow and Activity types

Use RegisterWorkflow() and RegisterActivity() to register types with a Worker. To register an Activity struct with multiple methods, pass the struct instance and the Worker gets access to all exported methods. Multiple Workflows and Activities can be registered on a single Worker.

Worker shutdown behavior

A Worker started with Run(worker.InterruptCh()) shuts down when the process receives SIGINT or SIGTERM. The Worker stops polling for new Tasks and waits for in-flight Tasks to finish, up to the WorkerStopTimeout set in worker.Options.

Lambda Worker registration example code

Example Lambda Worker code: package main imports lambdaworker and greeting. In main(), call lambdaworker.RunWorker(worker.WorkerDeploymentVersion{DeploymentName: "my-app", BuildID: "build-1"}, func(opts *lambdaworker.Options) error { opts.TaskQueue = "serverless-task-queue-1"; opts.RegisterWorkflowWithOptions(greeting.SampleWorkflow, workflow.RegisterOptions{VersioningBehavior: workflow.VersioningBehaviorPinned}); opts.RegisterActivity(greeting.HelloActivity); return nil }).

lambdaworker.RunWorker function signature and usage

Use the RunWorker function to start a Lambda-based Worker. Pass a WorkerDeploymentVersion and a callback function that registers Workflows and Activities. The function signature is: RunWorker(WorkerDeploymentVersion, callback func(*lambdaworker.Options) error). Worker Deployment Versioning is always enabled for Serverless Workers.

Lambda Worker registration methods available

The Options callback in RunWorker gives access to the same registration methods as traditional Workers: RegisterWorkflow, RegisterWorkflowWithOptions, RegisterActivity, RegisterActivityWithOptions, and RegisterNexusService.

Lambda Worker invocation lifecycle

Each Lambda invocation of a Temporal Serverless Worker starts a Worker, polls for Tasks, then gracefully shuts down before a configurable invocation deadline.

ShutdownDeadlineBuffer Lambda Worker setting

ShutdownDeadlineBuffer is specific to the lambdaworker package and controls how much time before the Lambda deadline the Worker begins graceful shutdown. Default value is WorkerStopTimeout + 2 seconds. If handling long-running Activities, increase WorkerStopTimeout, ShutdownDeadlineBuffer, and the Lambda invocation deadline together.

WorkerDeploymentVersion structure for Lambda Workers

WorkerDeploymentVersion is required for Lambda Workers and must include DeploymentName and BuildID fields. Example: worker.WorkerDeploymentVersion{DeploymentName: "my-app", BuildID: "build-1"}.

Cloud Run Worker versioning code example

Example showing how to create a versioned Cloud Run Worker with DeploymentOptions: ```go package main import ( "log" "os" "go.temporal.io/sdk/client" "go.temporal.io/sdk/contrib/envconfig" "go.temporal.io/sdk/worker" "go.temporal.io/sdk/workflow" "example.com/myapp" ) func main() { c, err := client.Dial(envconfig.MustLoadDefaultClientOptions()) if err != nil { log.Fatalln("Unable to create client", err) } defer c.Close() w := worker.New(c, os.Getenv("TEMPORAL_TASK_QUEUE"), worker.Options{ DeploymentOptions: worker.DeploymentOptions{ UseVersioning: true, Version: worker.WorkerDeploymentVersion{ DeploymentName: "my-app", BuildID: "build-1", }, }, }) w.RegisterWorkflowWithOptions(myapp.MyWorkflow, workflow.RegisterOptions{ VersioningBehavior: workflow.VersioningBehaviorPinned, }) w.RegisterActivity(myapp.MyActivity) if err := w.Run(worker.InterruptCh()); err != nil { log.Fatalln("Unable to start worker", err) } } ```

Load Cloud Run Worker connection settings from environment variables

Use the envconfig package to load Temporal Client configuration from environment variables and an optional TOML config file, so Worker code carries no Namespace or credentials. Call envconfig.MustLoadDefaultClientOptions() to load configuration with panics on invalid configuration, or envconfig.LoadDefaultClientOptions() to handle errors manually.

Cloud Run Worker requires Worker Versioning

A Cloud Run Worker on GCP Cloud Run worker pool requires Worker Versioning, which is the one addition to a standard Worker. Workflows and Activities are registered the same way as with any other Go Worker, and Temporal Cloud scales the pool up and down as work arrives and drains.

Set DeploymentOptions to enable versioning on Cloud Run Worker

Enable Worker Versioning by setting DeploymentOptions in worker.Options with UseVersioning set to true and a WorkerDeploymentVersion containing DeploymentName and BuildID. Both DeploymentName and BuildID together identify the Worker Deployment Version and must match the version created with temporal worker deployment create-version.

Cloud Run Worker needs no special package

A Cloud Run Worker needs no Cloud Run-specific package. Use the standard Go SDK to register Workflows and Activities the same way as with any other long-running Go Worker.

Go Cloud Run worker configuration

To run a Temporal Worker on GCP Cloud Run, use a standard Worker on a Cloud Run worker pool. Setup includes versioned Worker setup, connection configuration, and handling scale-in.

Go SDK serverless worker supported providers

The Go SDK supports two serverless compute providers for Temporal Workers. AWS Lambda support is available using the lambdaworker package. GCP Cloud Run support is available using a standard Worker on a Cloud Run worker pool. AWS Lambda is in Public Preview. GCP Cloud Run is in Pre-release and its APIs may change in backwards-incompatible ways.

Go lambdaworker package for AWS Lambda

The lambdaworker package allows running a Temporal Worker as an AWS Lambda function. It covers setup, configuration, Lambda-tuned defaults, observability, and the invocation lifecycle.

Enable Worker Sessions in Go SDK

To enable Worker Sessions in Go SDK, set the EnableSessionWorker field to true in the worker.Options structure when creating a worker. This enables task routing to ensure Activity Tasks are executed by the same Worker without manually specifying Task Queue names.

MaxConcurrentSessionExecutionSize worker option

The MaxConcurrentSessionExecutionSize field in worker.Options limits the maximum number of concurrent Sessions running on a Worker. By default, this field is set to a very large value. If a Worker hits this limitation, it will not accept new CreateSession() requests until an existing session completes. If a session cannot be created within CreationTimeout, CreateSession() returns an error.

CompleteSession releases Worker resources

CompleteSession() releases the resources reserved on the Worker and should be called as soon as the Session is no longer needed. It cancels the session context and therefore all Activity Executions using that Session Context. It is safe to call CompleteSession() on a failed Session, meaning it can be called from a defer function after the Session is successfully created.

CreateSession API for Sessions in workflows

Use the workflow.CreateSession API to create a Context object that contains Session metadata and can be passed to Activity execution calls. Pass an instance of workflow.Context and SessionOptions to CreateSession. If the context passed in already contains an open Session, CreateSession() returns an error. The Session uses the Task Queue name specified in ActivityOptions or StartWorkflowOptions.

SessionOptions structure for creating Sessions

SessionOptions contains two fields: CreationTimeout (the maximum time to wait for the Session to be created) and ExecutionTimeout (the maximum time the Session can execute). Both should be specified as time.Duration values when calling CreateSession.

Session failure when Worker dies

If the Worker executing a Session dies, the Session Context is cancelled. When using the returned Session Context to spawn Activity Executions, a workflow.ErrSessionFailed error is returned if the Session framework detects that the Worker executing the Session has died. If the Worker goes down between Activities, scheduled Activities meant for the Session Worker are canceled. If the Worker is still running when the next workflow.ExecuteActivity() is called, you get a workflow.ErrSessionFailed error.

Give your agent this brain