Skip to content

Commit 8886ec1

Browse files
committed
perf(non-determinism): updated encyclopedia pages to include activities to handle non-deterministic operations
1 parent 4b16811 commit 8886ec1

3 files changed

Lines changed: 26 additions & 42 deletions

File tree

docs/develop/java/workflows/basics.mdx

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -211,34 +211,23 @@ When you set the Workflow Type this way, the value of the `name` parameter does
211211

212212
## Workflow logic requirements {#workflow-logic-requirements}
213213

214-
Workflow logic is constrained by [deterministic execution requirements](/workflow-definition#deterministic-constraints).
215-
Therefore, each language is limited to the use of certain idiomatic techniques.
216-
However, each Temporal SDK provides a set of APIs that can be used inside your Workflow to interact with external (to the Workflow) application code.
214+
Workflow logic is constrained by [deterministic execution requirements](/workflow-definition#deterministic-constraints). Therefore, each language is limited to the use of certain idiomatic techniques. However, each Temporal SDK provides a set of APIs that can be used inside your Workflow to interact with external (to the Workflow) application code.
217215

218216
When defining Workflows using the Temporal Java SDK, the Workflow code must be written to execute effectively once and to completion.
219217

220218
The following constraints apply when writing Workflow Definitions:
221219

222-
- Do not use mutable global variables in your Workflow implementations.
223-
This will ensure that multiple Workflow instances are fully isolated.
224-
- Your Workflow code must be deterministic.
225-
Do not call non-deterministic functions (such as non-seeded random or `UUID.randomUUID()`) directly from the Workflow code.
226-
The Temporal SDK provides specific API for calling non-deterministic code in your Workflows.
227-
- Do not use programming language constructs that rely on system time.
228-
For example, only use `Workflow.currentTimeMillis()` to get the current time inside a Workflow.
229-
- Do not use native Java `Thread` or any other multi-threaded classes like `ThreadPoolExecutor`.
230-
Use `Async.function` or `Async.procedure`, provided by the Temporal SDK, to execute code asynchronously.
231-
- Do not use synchronization, locks, or other standard Java blocking concurrency-related classes besides those provided by the Workflow class.
232-
There is no need for explicit synchronization because multi-threaded code inside a Workflow is executed one thread at a time and under a global lock.
220+
- Do not use mutable global variables in your Workflow implementations. This will ensure that multiple Workflow instances are fully isolated.
221+
- Your Workflow code must be deterministic. Do not call non-deterministic functions (such as non-seeded random or `UUID.randomUUID()`) directly from the Workflow code. The Temporal SDK provides specific API for calling non-deterministic code in your Workflows.
222+
- For operations like calling external APIs, invoking LLMs, querying databases, or performing I/O, use Activities. Activities run outside Workflow replay and are retried reliably.
223+
- Do not use programming language constructs that rely on system time. For example, only use `Workflow.currentTimeMillis()` to get the current time inside a Workflow.
224+
- Do not use native Java `Thread` or any other multi-threaded classes like `ThreadPoolExecutor`. Use `Async.function` or `Async.procedure`, provided by the Temporal SDK, to execute code asynchronously.
225+
- Do not use synchronization, locks, or other standard Java blocking concurrency-related classes besides those provided by the Workflow class. There is no need for explicit synchronization because multi-threaded code inside a Workflow is executed one thread at a time and under a global lock.
233226
- Call `Workflow.sleep` instead of `Thread.sleep`.
234227
- Use `Promise` and `CompletablePromise` instead of `Future` and `CompletableFuture`.
235228
- Use `WorkflowQueue` instead of `BlockingQueue`.
236-
- Use `Workflow.getVersion` when making any changes to the Workflow code.
237-
Without this, any deployment of updated Workflow code might break already running Workflows.
238-
- Do not access configuration APIs directly from a Workflow because changes in the configuration might affect a Workflow Execution path.
239-
Pass it as an argument to a Workflow function or use an Activity to load it.
240-
- Use `DynamicWorkflow` when you need a default Workflow that can handle all Workflow Types that are not registered with a Worker.
241-
A single implementation can implement a Workflow Type which by definition is dynamically loaded from some external source.
242-
All standard `WorkflowOptions` and determinism rules apply to Dynamic Workflow implementations.
229+
- Use `Workflow.getVersion` when making any changes to the Workflow code. Without this, any deployment of updated Workflow code might break already running Workflows.
230+
- Do not access configuration APIs directly from a Workflow because changes in the configuration might affect a Workflow Execution path. Pass it as an argument to a Workflow function or use an Activity to load it.
231+
- Use `DynamicWorkflow` when you need a default Workflow that can handle all Workflow Types that are not registered with a Worker. A single implementation can implement a Workflow Type which by definition is dynamically loaded from some external source. All standard `WorkflowOptions` and determinism rules apply to Dynamic Workflow implementations.
243232

244233
Java Workflow reference: [https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/workflow/package-summary.html](https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/workflow/package-summary.html)

docs/encyclopedia/retry-policies.mdx

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ id: retry-policies
33
title: What is a Temporal Retry Policy?
44
sidebar_label: Retry Policies
55
description:
6-
Optimize your Workflow and Activity Task Executions with a custom Retry Policy on Temporal. Understand default
7-
retries, intervals, backoff, and maximum attempts for error handling.
6+
Optimize your Workflow and Activity Task Executions with a custom Retry Policy on Temporal Understand default retries, intervals, backoff, and maximum attempts for error handling.
87
toc_max_heading_level: 4
98
keywords:
109
- activities
@@ -18,22 +17,17 @@ import { CaptionedImage, RelatedReadContainer, RelatedReadItem } from '@site/src
1817
import Tabs from '@theme/Tabs';
1918
import TabItem from '@theme/TabItem';
2019

21-
A Retry Policy is a collection of settings that tells Temporal how and when to try again after something fails in a
22-
Workflow Execution or Activity Task Execution.
20+
A Retry Policy is a collection of settings that tells Temporal how and when to try again after something fails in a Workflow Execution or Activity Task Execution.
2321

2422
## Overview
2523

26-
Temporal's default behavior is to automatically retry an Activity that fails, so transient or intermittent failures
27-
require no action on your part. This behavior is defined by the Retry Policy.
24+
Temporal's default behavior is to automatically retry an Activity that fails, so transient or intermittent failures require no action on your part. This behavior is defined by the Retry Policy.
2825

29-
A Retry Policy is declarative. You do not need to implement your own logic for handling the retries; you only need to
30-
specify the desired behavior and Temporal will provide it.
26+
A Retry Policy is declarative. You do not need to implement your own logic for handling the retries; you only need to specify the desired behavior and Temporal will provide it.
3127

32-
In contrast to the Activities it contains, a Workflow Execution itself is not associated with a Retry Policy by default.
33-
This may seem counterintuitive, but Workflows and Activities perform different roles. Activities are intended for
34-
operations that may fail, so having a default Retry Policy increases the likelihood that they will ultimately complete
35-
successfully, even if the initial attempt failed. On the other hand, Workflows must be deterministic and are not
36-
intended to perform failure-prone operations. While it is possible to assign a Retry Policy to a Workflow Execution,
28+
In contrast to the Activities it contains, a Workflow Execution itself is not associated with a Retry Policy by default. This may seem counterintuitive, but Workflows and Activities perform different roles. Activities are intended for operations that may fail, so having a default Retry Policy increases the likelihood that they will ultimately complete successfully, even if the initial attempt failed.
29+
30+
On the other hand, Workflow code must be deterministic to support replay, and failure-prone or non-deterministic operations (API calls, LLM invocations, etc.) should be placed in Activities, which have built-in retry support. While it is possible to assign a Retry Policy to a Workflow Execution,
3731
this is not the default and it is uncommon to do so.
3832

3933
Retry Policies do not apply to Workflow Task Executions, which retry until the Workflow Execution Timeout (which is
@@ -136,14 +130,9 @@ re-execute upon failure; this is not typically true of Workflows. In most use ca
136130
an issue with the design or deployment of your application; for example, a permanent failure that may require different
137131
input data.
138132

139-
Retrying an entire Workflow Execution is not recommended due to Temporal's deterministic design. Since Workflows replay
140-
the same sequence of events to reach the same state, retrying the whole workflow would repeat the same logic without
141-
resolving the underlying issue that caused the failure. This repetition does not address problems related to external
142-
dependencies or unchanged conditions and can lead to unnecessary resource consumption and higher costs. Instead, it's
143-
more efficient to retry only the failed Activities. This approach targets specific points of failure, allowing the
144-
workflow to progress without redundant operations, thereby saving on resources and ensuring a more focused and effective
145-
error recovery process. If you need to retry parts of your Workflow Definition, we recommend you implement this in your
146-
Workflow code.
133+
Retrying an entire Workflow Execution is not recommended due to the deterministic nature of Workflow replay. Since Workflows replay the same sequence of events to reach the same state, retrying the whole Workflow would repeat the same logic without resolving the underlying issue that caused the failure. This repetition doesn't address problems related to external dependencies or unchanged conditions and can lead to unnecessary resource consumption and higher costs.
134+
135+
Instead, retry failed Activities within the Workflow, which is Temporal's default behavior. This approach targets specific points of failure, allowing the Workflow to progress without redundant operations, thereby saving on resources and ensuring a more focused and effective error recovery process. If you need to retry parts of your Workflow Definition, we recommend you implement this in your Workflow code.
147136

148137
## Custom Retry Policy
149138

docs/encyclopedia/workflow/workflow-definition.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,12 @@ A critical aspect of developing Workflow Definitions is ensuring that they are d
160160
Generally speaking, this means you must take care to ensure that any time your Workflow code is executed it makes the same Workflow API calls in the same sequence, given the same input.
161161
Some changes to those API calls are safe to make.
162162

163+
:::tip Note on determinism
164+
165+
Workflow code must be deterministic to support replay. To handle non-deterministic operations like API calls, LLM/AI invocations, database queries, and other external interactions, put them in Activities. Activities execute outside the replay path and are automatically retried so they don't cause non-determinism errors.
166+
167+
:::
168+
163169
For example, you can change:
164170

165171
- The input parameters, return values, and execution timeouts of Child Workflows and Activities

0 commit comments

Comments
 (0)