Skip to main content

Activity Execution

View Markdown

Start an Activity Execution​

Calls to spawn Activity Executions are written within a Workflow Definition. The call to spawn an Activity Execution generates the ScheduleActivityTask Command. This results in the set of three Activity Task related Events (ActivityTaskScheduled, ActivityTaskStarted, and ActivityTask[Closed]) in your Workflow Execution Event History.

A single instance of the Activities implementation is shared across multiple simultaneous Activity invocations. Activity implementation code should be idempotent.

The values passed to Activities through invocation parameters or returned through a result value are recorded in the Execution history. The entire Execution history is transferred from the Temporal Service to Workflow Workers when a Workflow state needs to recover. A large Execution history can thus adversely impact the performance of your Workflow.

Therefore, be mindful of the amount of data you transfer through Activity invocation parameters or Return Values. Otherwise, no additional limitations exist on Activity implementations.

To spawn an Activity Execution, call ExecuteActivity() inside your Workflow Definition. The API is available from the go.temporal.io/sdk/workflow package. The ExecuteActivity() API call requires an instance of workflow.Context, the Activity function name, and any variables to be passed to the Activity Execution. The Activity function name can be provided as a variable object (no quotations) or as a string. The benefit of passing the actual function object is that the framework can validate the parameters against the Activity Definition. The ExecuteActivity call returns a Future, which can be used to get the result of the Activity Execution.

go-sandbox/activities/basics/workflow.go

// ...
func YourWorkflowDefinition(ctx workflow.Context, param YourWorkflowParam) (*YourWorkflowResultObject, error) {
// ...
activityOptions := workflow.ActivityOptions{
// ...
StartToCloseTimeout: 10 * time.Second,
// ...
}
ctx = workflow.WithActivityOptions(ctx, activityOptions)
activityParam := YourActivityParam{
ActivityParamX: param.WorkflowParamX,
ActivityParamY: param.WorkflowParamY,
}

var a *YourActivityObject

var activityResult YourActivityResultObject

future := workflow.ExecuteActivity(ctx, a.YourActivityDefinition, activityParam)
// ...
if err := future.Get(ctx, &activityResult); err != nil {
return nil, err
}
// ...
}

Set the required Activity Timeouts​

Activity Execution semantics rely on several parameters. The only required value that needs to be set is either a Schedule-To-Close Timeout or a Start-To-Close Timeout. These values are set in the Activity Options.

To set an Activity Timeout in Go, create an instance of ActivityOptions from the go.temporal.io/sdk/workflow package, set the Activity Timeout field, and then use the WithActivityOptions() API to apply the options to the instance of workflow.Context.

Available timeouts are:

  • StartToCloseTimeout
  • ScheduleToCloseTimeout
  • ScheduleToStartTimeout

go-sandbox/activities/basics/workflow.go

// ...
activityOptions := workflow.ActivityOptions{
// ...
StartToCloseTimeout: 10 * time.Second,
// ...
// ScheduleToCloseTimeout: 10 * time.Second,
// ScheduleToStartTimeout: 10 * time.Second,
}
ctx = workflow.WithActivityOptions(ctx, activityOptions)
// ...

Go ActivityOptions reference​

Create an instance of ActivityOptions from the go.temporal.io/sdk/workflow package and use WithActivityOptions() to apply it to the instance of workflow.Context.

The instance of workflow.Context is then passed to the ExecuteActivity() call.

FieldRequiredType
ActivityIDNostring
TaskQueueNostring
ScheduleToCloseTimeoutYes (or StartToCloseTimeout)time.Duration
ScheduleToStartTimeoutNotime.Duration
StartToCloseTimeoutYes (or ScheduleToCloseTimeout)time.Duration
HeartbeatTimeoutNotime.Duration
WaitForCancellationNobool
RetryPolicyNoRetryPolicy

ActivityID​

  • Type: string
  • Default: None

go-sandbox/activities/basics/workflow.go

// ...
activityOptions := workflow.ActivityOptions{
ActivityID: "your-activity-id",
// ...
}
// ...

TaskQueue​

  • Type: string
  • Default: Inherits the TaskQueue name from the Workflow.

go-sandbox/activities/basics/workflow.go

// ...
activityOptions := workflow.ActivityOptions{
// ...
TaskQueue: "your-custom-task-queue-name",
// ...
}
// ...

ScheduleToCloseTimeout​

To set a Schedule-To-Close Timeout, create an instance of ActivityOptions from the go.temporal.io/sdk/workflow package, set the ScheduleToCloseTimeout field, and then use the WithActivityOptions() API to apply the options to the instance of workflow.Context.

This or StartToCloseTimeout must be set.

  • Type: time.Duration
  • Default: ∞ (infinity - no limit)

go-sandbox/activities/basics/workflow.go

// ...
activityOptions := workflow.ActivityOptions{
// ...
// ScheduleToCloseTimeout: 10 * time.Second,
// ...
}
// ...

ScheduleToStartTimeout​

To set a Schedule-To-Start Timeout, create an instance of ActivityOptions from the go.temporal.io/sdk/workflow package, set the ScheduleToStartTimeout field, and then use the WithActivityOptions() API to apply the options to the instance of workflow.Context.

  • Type: time.Duration
  • Default: ∞ (infinity - no limit)

go-sandbox/activities/basics/workflow.go

// ...
activityOptions := workflow.ActivityOptions{
// ...
// ScheduleToStartTimeout: 10 * time.Second,
// ...
}
// ...

StartToCloseTimeout​

To set a Start-To-Close Timeout, create an instance of ActivityOptions from the go.temporal.io/sdk/workflow package, set the StartToCloseTimeout field, and then use the WithActivityOptions() API to apply the options to the instance of workflow.Context.

This or ScheduleToCloseTimeout must be set.

  • Type: time.Duration
  • Default: Same as the ScheduleToCloseTimeout

go-sandbox/activities/basics/workflow.go

// ...
activityOptions := workflow.ActivityOptions{
// ...
StartToCloseTimeout: 10 * time.Second,
// ...
}
// ...

HeartbeatTimeout​

To set a Heartbeat Timeout, create an instance of ActivityOptions from the go.temporal.io/sdk/workflow package, set the HeartbeatTimeout field, and then use the WithActivityOptions() API to apply the options to the instance of workflow.Context.

go-sandbox/activities/basics/workflow.go

// ...
activityOptions := workflow.ActivityOptions{
// ...
HeartbeatTimeout: 5 * time.Second,
// ...
}
// ...

WaitForCancellation​

If true the Activity Execution will finish executing should there be a Cancellation request.

  • Type: bool
  • Default: false

go-sandbox/activities/basics/workflow.go

// ...
activityOptions := workflow.ActivityOptions{
// ...
WaitForCancellation: false,
// ...
}
// ...

RetryPolicy​

To set a RetryPolicy, create an instance of ActivityOptions from the go.temporal.io/sdk/workflow package, set the RetryPolicy field, and then use the WithActivityOptions() API to apply the options to the instance of workflow.Context.

go-sandbox/activities/basics/workflow.go

// ...
retryPolicy := &temporal.RetryPolicy{
InitialInterval: time.Second,
BackoffCoefficient: 2.0,
MaximumInterval: time.Second * 100, // 100 * InitialInterval
MaximumAttempts: 0, // Unlimited
NonRetryableErrorTypes: []string{}, // empty
}

Providing a Retry Policy here is a customization that overwrites individual Field defaults.

go-sandbox/activities/basics/workflow.go

// ...
retryPolicy := &temporal.RetryPolicy{
InitialInterval: time.Second,
BackoffCoefficient: 2.0,
MaximumInterval: time.Second * 100, // 100 * InitialInterval
MaximumAttempts: 0, // Unlimited
NonRetryableErrorTypes: []string{}, // empty
}
activityOptions := workflow.ActivityOptions{
// ...
RetryPolicy: retryPolicy,
// ...
}
// ...

Get the results of an Activity Execution​

The call to spawn an Activity Execution generates the ScheduleActivityTask Command and provides the Workflow with an Awaitable. Workflow Executions can either block progress until the result is available through the Awaitable or continue progressing, making use of the result when it becomes available.

The ExecuteActivity API call returns an instance of workflow.Future which has the following two methods:

  • Get(): Takes an instance of the workflow.Context, that was passed to the Activity Execution, and a pointer as parameters. The variable associated with the pointer is populated with the Activity Execution result. This call blocks until the results are available.
  • IsReady(): Returns true when the result of the Activity Execution is ready.

Call the Get() method on the instance of workflow.Future to get the result of the Activity Execution. The type of the result parameter must match the type of the return value declared by the Activity function.

go-sandbox/activities/basics/workflow.go

// ...
func YourWorkflowDefinition(ctx workflow.Context, param YourWorkflowParam) (*YourWorkflowResultObject, error) {
// ...
var a *YourActivityObject

var activityResult YourActivityResultObject

future := workflow.ExecuteActivity(ctx, a.YourActivityDefinition, activityParam)
// ...
if err := future.Get(ctx, &activityResult); err != nil {
return nil, err
}
// ...
}

Use the IsReady() method first to make sure the Get() call doesn't cause the Workflow Execution to wait on the result.

go-sandbox/activities/basics/workflow.go

// ...
func YourWorkflowDefinition(ctx workflow.Context, param YourWorkflowParam) (*YourWorkflowResultObject, error) {
// ...
var a *YourActivityObject

var activityResult YourActivityResultObject

future := workflow.ExecuteActivity(ctx, a.YourActivityDefinition, activityParam)
if future.IsReady() {
var yourActivityResult YourActivityResultObject
if err := future.Get(ctx, &yourActivityResult); err != nil {
return nil, err
}
}
// ...
}

It is idiomatic to invoke multiple Activity Executions from within a Workflow. Therefore, it is also idiomatic to either block on the results of the Activity Executions or continue on to execute additional logic, checking for the Activity Execution results at a later time.