Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0589a99
Clean up references/core/ai-integration.md
donald-pinckney Feb 13, 2026
22d90c5
Clean up references/core/common-gotchas.md
donald-pinckney Feb 13, 2026
a32152b
Clean up references/core/common-gotchas.md
donald-pinckney Feb 13, 2026
9ce8441
Clean up references/core/determinism.md
donald-pinckney Feb 13, 2026
519b2ea
Clean up references/core/determinism.md
donald-pinckney Feb 13, 2026
49c449a
Update error-reference.md
donald-pinckney Feb 17, 2026
d2a4af3
Update interactive-workflows.md
donald-pinckney Feb 17, 2026
e62865a
Clean up patterns.md
donald-pinckney Feb 17, 2026
324b532
Cut shell scripts
donald-pinckney Feb 17, 2026
5d3f79f
Edit troubleshooting.md
donald-pinckney Feb 17, 2026
19a9589
remove interceptors for now
donald-pinckney Feb 18, 2026
761b220
remove dynamic workflows
donald-pinckney Feb 18, 2026
4d032f4
clarify on heartbeating of async activity completions, and prompt it …
donald-pinckney Feb 18, 2026
8d77164
Improve references/python/advanced-features.md
donald-pinckney Feb 18, 2026
ceb40a0
Use explicit namespace in connect
donald-pinckney Feb 18, 2026
c61bc64
remove duplicated content from determinism.md, clean up
donald-pinckney Feb 18, 2026
236eab2
Improve references/python/data-handling.md
donald-pinckney Feb 18, 2026
43b1ed7
Prefer start_to_close_timeout
donald-pinckney Feb 18, 2026
cc593e3
don't explicitely provide defaults for retry policies
donald-pinckney Feb 18, 2026
24f0e3e
error-handling.md cleanup
donald-pinckney Feb 18, 2026
18cb1e8
move idempotency patterns to patterns.md
donald-pinckney Feb 18, 2026
03e8706
remove multi-param activities
donald-pinckney Feb 18, 2026
3f7dc9d
small edits
donald-pinckney Feb 18, 2026
9163fa2
Unify sandbox stuff into one file
donald-pinckney Feb 18, 2026
4c288cf
local activities aren't experimental
donald-pinckney Feb 18, 2026
b8b47ca
Clean up references/python/sync-vs-async.md
donald-pinckney Feb 18, 2026
9bc285f
Cleanup observability.md, remove duplicated search attributes
donald-pinckney Feb 19, 2026
f455d39
Cut otel for now
donald-pinckney Feb 19, 2026
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
Prev Previous commit
Next Next commit
Clean up patterns.md
  • Loading branch information
donald-pinckney committed Feb 17, 2026
commit e62865a39c05843c03786230140dc1caff99fe45
53 changes: 42 additions & 11 deletions references/core/patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Overview

Common patterns for building robust Temporal workflows. For language-specific implementations, see the Python or TypeScript references.
Common patterns for building robust Temporal workflows. See the language-specific references for the language you are working in.

## Signals

Expand Down Expand Up @@ -45,6 +45,7 @@ Client Workflow
- Read-only - must not modify state
- Not recorded in history
- Executes on the worker, not persisted
- Can run even on completed workflows

**Example Flow**:
```
Expand All @@ -68,7 +69,7 @@ Client Workflow
**Characteristics**:
- Synchronous - caller waits for completion
- Can mutate state AND return values
- Supports validators to reject invalid updates
- Supports validators to reject invalid updates before they even get persisted into history
- Recorded in history

**Example Flow**:
Expand All @@ -82,12 +83,9 @@ Client Workflow

## Child Workflows

**Purpose**: Break complex workflows into smaller, reusable pieces.

**When to Use**:
- Prevent history from growing too large
- Isolate failure domains (child can fail without failing parent)
- Reuse workflow logic across multiple parents
- Different retry policies for different parts

**Characteristics**:
Expand All @@ -101,6 +99,8 @@ Client Workflow
- `ABANDON` - Child continues running independently
- `REQUEST_CANCEL` - Cancellation requested but not forced

**Note:** Do not need to use child workflows simply for breaking complex logic down into smaller pieces. Standard programming abstractions within a workflow can already be used for that.

## Continue-as-New

**Purpose**: Prevent unbounded history growth by "restarting" with fresh history.
Expand Down Expand Up @@ -166,7 +166,7 @@ On failure at step 3:
- Reducing total workflow duration

**Patterns**:
- `Promise.all()` / `asyncio.gather()` - Wait for all
- `Promise` / `asyncio` - Use traditional concurrency helpers (e.g. wait for all, wait for first, etc)
- Partial failure handling - Continue with successful results

## Entity Workflow Pattern
Expand Down Expand Up @@ -208,22 +208,53 @@ Entity Workflow (user-123)
**Characteristics**:
- Timers are durable (persisted in history)
- Can be cancelled
- Combine with cancellation scopes for timeouts

## Polling Pattern
## Polling Patterns

**Purpose**: Repeatedly check external state until condition met.
### Frequent Polling

**Purpose**: Frequently (once per second of faster) repeatedly check external state until condition met.

**Implementation**:

```
# Inside Activity (polling_activity):
while not condition_met:
result = await check_activity()
result = await call_external_api()
if result.done:
break
activity.heartbeat("Invoking activity")
await sleep(poll_interval)


# In workflow code:
workflow.execute_activity(
polling_activity,
PollingActivityInput(...),
start_to_close_timeout=timedelta(seconds=60),
heartbeat_timeout=timedelta(seconds=2),
)
```

**Best Practice**: Use exponential backoff for polling intervals.
To ensure that polling_activity is restarted in a timely manner, we make sure that it heartbeats on every iteration. Note that heartbeating only works if we set the heartbeat_timeout to a shorter value than the Activity start_to_close_timeout timeout

**Advantage:** Because the polling loop is inside the activity, this does not pollute the workflow history.

### Infrequent Polling

**Purpose**: Infrequently (once per minute or slower) repeatedly poll an external service.

**Implementation**:

Define an Activty which fails (raises an exception) exactly when polling is not completed.

The polling loop is accomplised via activity retries, by setting the following Retry options:
- backoff_coefficient: to 1
- initial_interval: to the polling interval (e.g. 60 seconds)

This will enable the Activity to be retried exactly on the set interval.

**Advantage:** Individual Activity retries are not recorded in Workflow History, so this approach can poll for a very long time without affecting the history size.

## Choosing Between Patterns

Expand Down