Skip to content

Commit 96475d5

Browse files
authored
chore(activity execution): updated explanation of task tokens (#4136)
1 parent 3a8c022 commit 96475d5

1 file changed

Lines changed: 75 additions & 46 deletions

File tree

docs/encyclopedia/activities/activity-execution.mdx

Lines changed: 75 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,28 @@ An Activity Execution is the full chain of [Activity Task Executions](/tasks#act
3939
- [How to start an Activity Execution using the .NET SDK](/develop/dotnet/core-application#activity-execution)
4040

4141
:::
42-
<CaptionedImage
43-
src="/diagrams/activity-execution.svg"
44-
title="Activity Execution"
45-
/>
4642

47-
You can customize [Activity Execution timeouts](/encyclopedia/detecting-activity-failures#start-to-close-timeout) and [retry policies](/encyclopedia/retry-policies).
43+
<CaptionedImage src="/diagrams/activity-execution.svg" title="Activity Execution" />
4844

49-
If an Activity Execution fails (because it exhausted all retries, threw a [non-retryable error](/encyclopedia/retry-policies#non-retryable-errors), or was canceled), the error is returned to the [Workflow](/workflows), which decides how to handle it.
45+
You can customize [Activity Execution timeouts](/encyclopedia/detecting-activity-failures#start-to-close-timeout) and
46+
[retry policies](/encyclopedia/retry-policies).
47+
48+
If an Activity Execution fails (because it exhausted all retries, threw a
49+
[non-retryable error](/encyclopedia/retry-policies#non-retryable-errors), or was canceled), the error is returned to the
50+
[Workflow](/workflows), which decides how to handle it.
5051

5152
:::note
5253

53-
Temporal guarantees that an Activity Task either runs or timeouts.
54-
There are multiple failure scenarios when an Activity Task is lost.
55-
It can be lost during delivery to a Worker or after the Activity Function is called and the Worker crashed.
54+
Temporal guarantees that an Activity Task either runs or timeouts. There are multiple failure scenarios when an Activity
55+
Task is lost. It can be lost during delivery to a Worker or after the Activity Function is called and the Worker
56+
crashed.
5657

57-
Temporal doesn't detect task loss directly.
58-
It relies on [Start-To-Close timeout](/encyclopedia/detecting-activity-failures#start-to-close-timeout).
59-
If the Activity Task times out, the Activity Execution will be retried according to the Activity Execution Retry Policy.
58+
Temporal doesn't detect task loss directly. It relies on
59+
[Start-To-Close timeout](/encyclopedia/detecting-activity-failures#start-to-close-timeout). If the Activity Task times
60+
out, the Activity Execution will be retried according to the Activity Execution Retry Policy.
6061

61-
In scenarios where the Activity Execution Retry Policy is set to `1` and a Timeout occurs, the Activity Execution will not be tried.
62+
In scenarios where the Activity Execution Retry Policy is set to `1` and a Timeout occurs, the Activity Execution will
63+
not be tried.
6264

6365
:::
6466

@@ -73,40 +75,49 @@ Activities must heartbeat to receive cancellations from a Temporal Service.
7375

7476
An Activity may receive Cancellation if:
7577

76-
- The Activity was requested to be Cancelled. This can often cascade from Workflow Cancellation, but not always—SDKs have ways to stop Cancellation from cascading. {/* TODO link to workflow cancellation */}
77-
- The Activity was considered failed by the Server because any of the Activity timeouts have triggered (for example, the Server didn't receive a heartbeat within the Activity's Heartbeat timeout). The [Cancelled Failure](/references/failures#cancelled-failure) that the Activity receives will have `message: 'TIMED_OUT'`.
78-
- The Workflow Run reached a [Closed state](/workflow-execution#workflow-execution-status), in which case the Cancelled Failure will have `message: 'NOT_FOUND'`.
78+
- The Activity was requested to be Cancelled. This can often cascade from Workflow Cancellation, but not always—SDKs
79+
have ways to stop Cancellation from cascading. {/* TODO link to workflow cancellation */}
80+
- The Activity was considered failed by the Server because any of the Activity timeouts have triggered (for example, the
81+
Server didn't receive a heartbeat within the Activity's Heartbeat timeout). The
82+
[Cancelled Failure](/references/failures#cancelled-failure) that the Activity receives will have
83+
`message: 'TIMED_OUT'`.
84+
- The Workflow Run reached a [Closed state](/workflow-execution#workflow-execution-status), in which case the Cancelled
85+
Failure will have `message: 'NOT_FOUND'`.
7986
- In some SDKs:
8087
- The Worker is shutting down.
81-
- An Activity sends a Heartbeat but the Heartbeat details can't be converted by the Worker's configured [Data Converter](/dataconversion). This fails the Activity Task Execution with an Application Failure.
82-
- The Activity timed out on the Worker side and is not Heartbeating or the Temporal Service hasn't relayed a Cancellation.
88+
- An Activity sends a Heartbeat but the Heartbeat details can't be converted by the Worker's configured
89+
[Data Converter](/dataconversion). This fails the Activity Task Execution with an Application Failure.
90+
- The Activity timed out on the Worker side and is not Heartbeating or the Temporal Service hasn't relayed a
91+
Cancellation.
8392

84-
There are different ways to receive Cancellation depending on the SDK. {/* TODO link to dev guide */}
85-
An Activity may accept or ignore Cancellation:
93+
There are different ways to receive Cancellation depending on the SDK. {/* TODO link to dev guide */} An Activity may
94+
accept or ignore Cancellation:
8695

8796
- To allow Cancellation to happen, let the Cancellation Failure propagate.
8897
- To ignore Cancellation, catch it and continue executing.
8998

9099
Some SDKs have ways to shield tasks from being stopped while still letting the Cancellation propagate.
91100

92-
The Workflow can also decide if it wants to wait for the Activity Cancellation to be accepted or to proceed without waiting.
101+
The Workflow can also decide if it wants to wait for the Activity Cancellation to be accepted or to proceed without
102+
waiting.
93103

94-
Cancellation can only be requested a single time.
95-
If you try to cancel your Activity Execution more than once, it will not receive more than one Cancellation request.
104+
Cancellation can only be requested a single time. If you try to cancel your Activity Execution more than once, it will
105+
not receive more than one Cancellation request.
96106

97107
## What is an Activity Id? {#activity-id}
98108

99-
The identifier for an [Activity Execution](#activity-execution).
100-
The identifier can be generated by the system, or it can be provided by the Workflow code that spawns the Activity Execution.
101-
The identifier is unique among the open Activity Executions of a [Workflow Run](/workflow-execution/workflowid-runid#run-id).
102-
(A single Workflow Run may reuse an Activity Id if an earlier Activity Execution with the same Id has closed.)
109+
The identifier for an [Activity Execution](#activity-execution). The identifier can be generated by the system, or it
110+
can be provided by the Workflow code that spawns the Activity Execution. The identifier is unique among the open
111+
Activity Executions of a [Workflow Run](/workflow-execution/workflowid-runid#run-id). (A single Workflow Run may reuse
112+
an Activity Id if an earlier Activity Execution with the same Id has closed.)
103113

104114
An Activity Id can be used to [complete the Activity asynchronously](#asynchronous-activity-completion).
105115

106116
## What is Asynchronous Activity Completion? {#asynchronous-activity-completion}
107117

108-
Asynchronous Activity Completion is a feature that enables an Activity Function to return without causing the Activity Execution to complete.
109-
The Temporal Client can then be used from anywhere to both Heartbeat Activity Execution progress and eventually complete the Activity Execution and provide a result.
118+
Asynchronous Activity Completion is a feature that enables an Activity Function to return without causing the Activity
119+
Execution to complete. The Temporal Client can then be used from anywhere to both Heartbeat Activity Execution progress
120+
and eventually complete the Activity Execution and provide a result.
110121

111122
How to complete an Activity Asynchronously in:
112123

@@ -119,45 +130,56 @@ How to complete an Activity Asynchronously in:
119130

120131
### When to use Async Completion
121132

122-
When an external system has the final result of a computation that is started by an Activity, there are three main ways of getting the result to the Workflow:
133+
When an external system has the final result of a computation that is started by an Activity, there are three main ways
134+
of getting the result to the Workflow:
123135

124136
1. The external system uses Async Completion to complete the Activity with the result.
125-
2. The Activity completes normally, without the result. Later, the external system sends a Signal to the Workflow with the result.
126-
3. A subsequent Activity [polls the external system](https://community.temporal.io/t/what-is-the-best-practice-for-a-polling-activity/328/2) for the result.
137+
2. The Activity completes normally, without the result. Later, the external system sends a Signal to the Workflow with
138+
the result.
139+
3. A subsequent Activity
140+
[polls the external system](https://community.temporal.io/t/what-is-the-best-practice-for-a-polling-activity/328/2)
141+
for the result.
127142

128-
If you don't have control over the external system—that is, you can't add Async Completion or a Signal to its code—then
143+
If you don't have control over the external system — that is, you can't add Async Completion or a Signal to its code —
144+
then:
129145

130146
- you can poll (#3), or
131-
- if the external system can reliably call a webhook (and retry calling in the case of failure), you can write a webhook handler that sends a Signal to the Workflow (#2).
147+
- if the external system can reliably call a webhook (and retry calling in the case of failure), you can write a webhook
148+
handler that sends a Signal to the Workflow (#2).
132149

133-
The decision between using #1 vs #2 involves a few factors.
134-
Use Async Completion if
150+
The decision between using #1 vs #2 involves a few factors. Use Async Completion if:
135151

136152
- the external system is unreliable and might fail to Signal, or
137153
- you want the external process to Heartbeat or receive Cancellation.
138154

139-
Otherwise, if the external system can reliably be trusted to do the task and Signal back with the result, and it doesn't need to Heartbeat or receive Cancellation, then you may want to use Signals.
155+
Otherwise, if the external system can reliably be trusted to do the task and Signal back with the result, and it doesn't
156+
need to Heartbeat or receive Cancellation, then you may want to use Signals.
140157

141-
The benefit to using Signals has to do with the timing of failure retries.
142-
For example, consider an external process that is waiting for a human to review something and respond, and they could take up to a week to do so.
143-
If you use Async Completion (#1), you would
158+
The benefit to using Signals has to do with the timing of failure retries. For example, consider an external process
159+
that is waiting for a human to review something and respond, and they could take up to a week to do so. If you use Async
160+
Completion (#1), you would:
144161

145-
- set a [Start-To-Close Timeout](/encyclopedia/detecting-activity-failures#start-to-close-timeout) of one week on the Activity,
162+
- set a [Start-To-Close Timeout](/encyclopedia/detecting-activity-failures#start-to-close-timeout) of one week on the
163+
Activity,
146164
- in the Activity, notify the external process you need the human review, and
147165
- have the external process Asynchronously Complete the Activity when the human responds.
148166

149-
If the Activity fails on the second step to notify the external system and doesn't throw an error (for example, if the Worker dies), then the Activity won't be retried for a week, when the Start-To-Close Timeout is hit.
167+
If the Activity fails on the second step to notify the external system and doesn't throw an error (for example, if the
168+
Worker dies), then the Activity won't be retried for a week, when the Start-To-Close Timeout is hit.
150169

151170
If you use Signals, you would:
152171

153-
- set a [Start-To-Close Timeout](/encyclopedia/detecting-activity-failures#start-to-close-timeout) of one minute on the Activity,
172+
- set a [Start-To-Close Timeout](/encyclopedia/detecting-activity-failures#start-to-close-timeout) of one minute on the
173+
Activity,
154174
- in the Activity, notify the external process you need the human review,
155175
- complete the Activity without the result, and
156176
- have the external process Signal the Workflow when the human responds.
157177

158-
If the Activity fails on the second step to notify the external system and doesn't throw an error, then the Activity will be retried in a minute.
178+
If the Activity fails on the second step to notify the external system and doesn't throw an error, then the Activity
179+
will be retried in a minute.
159180

160-
In the second scenario, the failure is retried sooner. This is particularly helpful in scenarios like this in which the external process might take a long time.
181+
In the second scenario, the failure is retried sooner. This is particularly helpful in scenarios like this in which the
182+
external process might take a long time.
161183

162184
### What is a Task Token? {#task-token}
163185

@@ -166,4 +188,11 @@ A Task Token is a unique identifier for an [Activity Task Execution](/tasks#acti
166188
[Asynchronous Activity Completion](#asynchronous-activity-completion) calls take either of the following as arguments:
167189

168190
- a Task Token, or
169-
- an [Activity Id](#activity-id), a [Workflow Id](/workflow-execution/workflowid-runid#workflow-id), and optionally a [Run Id](/workflow-execution/workflowid-runid#run-id).
191+
- an [Activity Id](#activity-id), a [Workflow Id](/workflow-execution/workflowid-runid#workflow-id), and optionally a
192+
[Run Id](/workflow-execution/workflowid-runid#run-id).
193+
194+
Since a Task Token is unique for an Activity execution, retries can cause a remote service using the Task Token to end
195+
up with an invalid one. For example, an Activity might fail after passing its current Task Token to a remote service,
196+
but before returning the complete async error, leaving that service with a Task Token that's no longer valid.
197+
198+
To avoid this risk, you can provide the Activity Id and Workflow Id to the remote service instead of the Task Token.

0 commit comments

Comments
 (0)