Skip to content

Improve determinism explanation #3614

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 35 additions & 9 deletions docs/encyclopedia/workflow/workflow-definition.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
id: workflow-definition
title: Temporal Workflow Definition
sidebar_label: Workflow Definition
sidebar_label: Workflow Definition
description: A Workflow Definition in Temporal is the code that defines the constraints of a Workflow Execution.
slug: /workflow-definition
toc_max_heading_level: 4
Expand Down Expand Up @@ -156,13 +156,39 @@ We strongly recommend that you write a Workflow Definition in a language that ha

### Deterministic constraints {#deterministic-constraints}

A critical aspect of developing Workflow Definitions is ensuring they exhibit certain deterministic traits – that is, making sure that the same Commands are emitted in the same sequence, whenever a corresponding Workflow Function Execution (instance of the Function Definition) is re-executed.

The execution semantics of a Workflow Execution include the re-execution of a Workflow Function, which is called a [Replay](/workflow-execution#replay).
The use of Workflow APIs in the function is what generates [Commands](/workflow-execution#command).
Commands tell the Temporal Service which Events to create and add to the Workflow Execution's [Event History](/workflow-execution/event#event-history).
When a Workflow Function executes, the Commands that are emitted are compared with the existing Event History.
If a corresponding Event already exists within the Event History that maps to the generation of that Command in the same sequence, and some specific metadata of that Command matches with some specific metadata of the Event, then the Function Execution progresses.
A critical aspect of developing Workflow Definitions is ensuring they are deterministic. 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. Some changes to those
API calls are safe to make. For example, you can change:

- The input parameters, return values, and execution timeouts of Child Workflows and Activities
- However, it is not safe to change the types or IDs of Child Workflows or Activities
- The input parameters used to Signal an external Workflow
- The duration of Timers (although changing them to 0 is not safe in all SDKs)
- Add or remove calls to Workflow APIs that don't produce [Commands](/workflow-execution#command) (e.g., `workflow.GetInfo` in the Go SDK or its equivalent in other SDKs)

The following Workflow API calls all can produce Commands, and thus must not be reordered, added, or
removed without proper [Versioning techniques](#workflow-versioning):

- Starting or cancelling a Timer
- Scheduling or cancelling Activity Executions (including local Activities)
- Starting or cancelling Child Workflow executions
- Signalling or cancelling signals to external Workflow Executions
- Scheduling or cancelling Nexus operations
- Ending the Workflow Execution in any way (completing, failing, cancelling, or continuing-as-new)
- `Patched` or `GetVersion` calls for Versioning (although they may be added or removed according to the [patching](#patching) rules)
- Upserting Workflow Search Attributes
- Upserting Workflow Memos
- Running a SideEffect or MutableSideEffect

For a complete reference, see the [Command reference](/references/commands).

More formally, the use of certain Workflow APIs in the function is what generates Commands. Commands
tell the Temporal Service which Events to create and add to the Workflow Execution's [Event History](/workflow-execution/event#event-history). When the Workflow's code
[replays](/workflow-execution#replay), the Commands that are emitted are compared with the existing
Event History. If a corresponding Event already exists within the Event History that matches that
command, then the Execution progresses. See [here](/encyclopedia/event-history/) for a detailed
walkthrough of the process.

For example, using an SDK's "Execute Activity" API generates the [ScheduleActivityTask](/references/commands#scheduleactivitytask) Command.
When this API is called upon re-execution, that Command is compared with the Event that is in the same location within the sequence.
Expand Down Expand Up @@ -242,7 +268,7 @@ A versioning strategy is even more important if your Workflow Executions live lo

Apart from the ability to create new Task Queues for Workflow Types with the same name, the Temporal Platform provides Workflow Patching APIs and Worker Build Id–based versioning features.

#### Patching
#### Patching {#patching}

Patching APIs enable the creation of logical branching inside a Workflow Definition based on a developer-specified version identifier.
This feature is useful for Workflow Definition logic that needs to be updated but still has running Workflow Executions that depend on it.
Expand Down