Skip to content
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

SDK-1486: Python update docs #2976

Merged
merged 25 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c0bc05d
Edit top-level message-passing docs
dandavison Aug 7, 2024
8ba4744
Python update docs
dandavison Jul 24, 2024
1d137b2
Update dynamic handlers section
dandavison Aug 7, 2024
68b13a1
Drop exclamation marks
dandavison Aug 7, 2024
2409298
DEV: use temp URL for sample
dandavison Aug 7, 2024
a95e66f
Get rid of cruft before the code sample
dandavison Aug 7, 2024
5225a38
Changes in response to @drewhoskins-temporal's code review
dandavison Aug 8, 2024
3358330
Add emojis to code comments
dandavison Aug 8, 2024
7a78979
Updates from an initial subset of @cretz's comments
dandavison Aug 8, 2024
5e084a9
More updates from review
dandavison Aug 9, 2024
d13a0d6
Break up code sample
dandavison Aug 9, 2024
9403c49
WIP: exceptions
dandavison Aug 9, 2024
b6a05a5
Further evolution of "Exceptions" section (now Troubleshooting)
dandavison Aug 13, 2024
6572b12
Clarify benefit of Update
dandavison Aug 13, 2024
47e01cf
Merge branch 'main' into sdk-1486-python-message-handlers
fairlydurable Aug 13, 2024
bb60ed2
Move Message-handling patterns ahead of Troubleshooting
dandavison Aug 13, 2024
ccf39ea
Add some intro and make Query snippet more self-contained
dandavison Aug 14, 2024
7d481ec
EDU-671: Brings Python Workflow Message Handling into docs compliance…
fairlydurable Aug 21, 2024
7d86210
Merge branch 'main' into sdk-1486-python-message-handlers
dandavison Aug 21, 2024
2820990
Hold a lock in the async update example
dandavison Aug 21, 2024
1d5b39c
Merge remote-tracking branch 'origin/main' into sdk-1486-python-messa…
dandavison Aug 21, 2024
6446f01
Mention workflow.current_update_info
dandavison Aug 21, 2024
11411c8
Merge remote-tracking branch 'origin/main' into sdk-1486-python-messa…
dandavison Aug 22, 2024
01abafd
Merge branch 'main' into sdk-1486-python-message-handlers
fairlydurable Aug 22, 2024
d48ef20
Fix error in existing docs
dandavison Aug 22, 2024
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
745 changes: 487 additions & 258 deletions docs/develop/python/message-passing.mdx

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions docs/encyclopedia/application-message-passing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ keywords:
import PrettyImage from '@site/src/components/pretty-image/PrettyImage';
import { RelatedReadContainer, RelatedReadItem } from '@site/src/components/related-read/RelatedRead';

Workflows can be thought of as stateful web services that can receive messages. The Workflow can have powerful message handlers akin to endpoints that can react to the incoming messages in combination with the current state of the Workflow.
Temporal supports three types of messages: Signals, Queries, and Updates.
To define these, consider these messages from the perspective of the client making the request:
Workflows can be thought of as stateful web services that can receive messages.
The Workflow can have powerful message handlers akin to endpoints that react to the incoming messages in combination with the current state of the Workflow.
Temporal supports three types of messages: Signals, Queries, and Updates:

- Queries are read requests. They can read the current state of the Workflow but cannot block in doing so.
- Signals are asynchronous write requests. They cause changes in the running Workflow, but you cannot await any response or error.
Expand Down Expand Up @@ -145,8 +145,8 @@ In most languages (except Go), you may call `executeUpdate` to complete an Updat

Alternatively, to start an Update, you may call `startUpdate` and pass in the Workflow Update Stage as an argument. You have two choices on what to await:

- Accepted - wait til the Worker is contacted, which ensures that the Update is persisted. See [Update Validators](#update-validators) for more information.
- Completed - wait til the handler finishes and returns a result. (This is equivalent to `executeUpdate`.)
- Accepted - wait until the Worker is contacted, which ensures that the Update is persisted. See [Update Validators](#update-validators) for more information.
- Completed - wait until the handler finishes and returns a result. (This is equivalent to `executeUpdate`.)

The start call will give you a handle you can use to track the Update, determine whether it was Accepted, and ultimately get its result or an error.

Expand Down Expand Up @@ -231,7 +231,7 @@ A Signal or Update handler can block waiting for the Workflow to reach a certain
Sometimes, you need your message handler to wait for long-running operations such as executing an Activity. When this happens, the handler will yield control back to [the loop](#message-handler-concurrency). This means that your handlers can have race conditions if you’re not careful.
You can guard your handlers with concurrency primitives like mutexes or semaphores, but you should use versions of these primitives provided for Workflows in most languages. See the links below for examples of how to use them in your SDK.

#### Inject work into the main Workflow
#### Inject work into the main Workflow {#injecting-work-into-main-workflow}

Sometimes you want to process work provided by messages in the main Workflow. Perhaps you’d like to accumulate several messages before acting on any of them. For example, message handlers might put work into a queue, which can then be picked up and processed in an event loop that you yourself write.
This option is considered advanced but offers powerful flexibility. And if you serialize the handling of your messages inside your main Workflow, you can avoid using concurrency primitives like mutexes and semaphores. See the links above for how to do this in your SDK.
Expand All @@ -244,7 +244,7 @@ If you don’t need to ensure that your handlers complete, you may specify your

See the links below for how to ensure handlers are finished in your SDK.

#### Ensuring your messages are processed exactly once
#### Ensuring your messages are processed exactly once {#exactly-once-message-processing}

Many developers want their message handlers to run exactly once--to be idempotent--in cases where the same Signal or Update is delivered twice or sent by two different call sites. Temporal deduplicates messages for you on the server, but there is one important case when you need to think about this yourself when authoring a Workflow, and one when sending Signals and Updates.

Expand Down Expand Up @@ -300,7 +300,7 @@ Once the Update handler is finished and has returned a value, the operation is c
</RelatedReadContainer>
-->

### Exceptions in message handlers
### Exceptions in message handlers {#exceptions}

When throwing an exception in a message handler, you should decide whether to make it an [Application Failure](/references/failures#application-failure). The implications are different between Signals and Updates.

Expand All @@ -324,7 +324,7 @@ If you throw any other exception, by default, it will cause a [Workflow Task Fai

#### Errors and panics in message handlers in the Go SDK

In Go, returning an error behaves like an [Application Failure](/references/failures#application-failure) in the other SDKs. Panics behave like non-Application Failure exceptions in other languages, in that they fail the Signal or Update handler tasks.
In Go, returning an error behaves like an [Application Failure](/references/failures#application-failure) in the other SDKs. Panics behave like non-Application Failure exceptions in other languages, in that they cause a [Workflow Task Failure](/references/failures#workflow-task-failures).

### Writing Signal Handlers {#writing-signal-handlers}

Expand All @@ -334,7 +334,7 @@ Use these links to see a simple Signal handler.
<RelatedReadItem path="/develop/go/message-passing#handle-signal" text="Handle Signals in Go" archetype="feature-guide" />
<RelatedReadItem path="/develop/java/message-passing#handle-signal" text="Handle Signals in Java" archetype="feature-guide" />
<RelatedReadItem path="/develop/php/message-passing#handle-signal" text="Handle Signals in PHP" archetype="feature-guide" />
<RelatedReadItem path="/develop/python/message-passing#handle-signal" text="Handle Signals in Python" archetype="feature-guide" />
<RelatedReadItem path="/develop/python/message-passing#signals" text="Handle Signals in Python" archetype="feature-guide" />
<RelatedReadItem path="/develop/typescript/message-passing#handle-signal" text="Handle Signals in Typescript" archetype="feature-guide" />
<!-- DOES NOT EXIST YET
<RelatedReadItem path="/develop/dotnet/message-passing#handle-signal" text="Handle Signals in .NET" archetype="feature-guide" />
Expand Down Expand Up @@ -364,7 +364,7 @@ Author queries using these per-language guides.
<RelatedReadItem path="/develop/go/message-passing#handle-query" text="Handle Queries in Go" archetype="feature-guide" />
<RelatedReadItem path="/develop/java/message-passing#handle-query" text="Handle Queries in Java" archetype="feature-guide" />
<RelatedReadItem path="/develop/php/message-passing#handle-query" text="Handle Queries in PHP" archetype="feature-guide" />
<RelatedReadItem path="/develop/python/message-passing#handle-query" text="Handle Queries in Python" archetype="feature-guide" />
<RelatedReadItem path="/develop/python/message-passing#queries" text="Handle Queries in Python" archetype="feature-guide" />
<RelatedReadItem path="/develop/typescript/message-passing#handle-query" text="Handle Queries in Typescript" archetype="feature-guide" />
<!-- DOES NOT EXIST YET
<RelatedReadItem path="/develop/dotnet/message-passing#handle-query" text="Handle Queries in .NET" archetype="feature-guide" />
Expand Down
13 changes: 6 additions & 7 deletions docs/references/failures.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,13 @@ This is the only type of Failure created and thrown by user code.
- Python: [ApplicationError](https://python.temporal.io/temporalio.exceptions.ApplicationError.html)
- Proto: [ApplicationFailureInfo](https://api-docs.temporal.io/#temporal.api.failure.v1.ApplicationFailureInfo) and [Failure](https://api-docs.temporal.io/#temporal.api.failure.v1.Failure)

### Throw from Workflows
### Errors in Workflows

Only Workflow errors that are Temporal Failures cause the Workflow Execution to fail; all other errors cause the Workflow Task to fail and be retried (except for Go, where any error returned from the Workflow fails the Execution, and a panic fails the Task).
Most types of Temporal Failures automatically occur, like a [Cancelled Failure](#cancelled-failure) when the Workflow is Cancelled or an [Activity Failure](#activity-failure) when an Activity Fails.
You can also explicitly fail the Workflow Execution by throwing (or returning, depending on the SDK) an Application Failure.
An error in a Workflow can cause either a **Workflow Task Failure** (the Task will be retried) or a **Workflow Execution Failure** (the Workflow is marked as failed).

If a Workflow raises an exception, it will either be retried, or marked as failed.
This is dependent on whether the exception is a **Workflow Task Failure** or a **Workflow Execution Failure**.
Only Workflow exceptions that are Temporal Failures cause the Workflow Execution to fail; all other exceptions cause the Workflow Task to fail and be retried (in Go, any error returned from the Workflow fails the Workflow Execution, and a panic fails the Workflow Task).
Most types of Temporal Failures occur automatically, like a [Cancelled Failure](#cancelled-failure) when the Workflow is Cancelled or an [Activity Failure](#activity-failure) when an Activity Fails.
You can also explicitly fail the Workflow Execution by throwing an Application Failure (returning any error in Go).

#### Workflow Task Failures

Expand All @@ -67,7 +66,7 @@ An `ApplicationError`, an extension of `FailureError`, can be raised in a Workfl
Workflow Execution Failures put the Workflow Execution into the "Failed" state and no more attempts will be made in progressing this execution.
If you are creating custom exceptions you would either need to extend the `ApplicationError` class—a child class of `FailureError`— or explicitly state that this exception is a Workflow Execution Failure by raising a new `ApplicationError`.

### Throw from Activities
### Errors in Activities

In Activities, you can either throw an Application Failure or another Error to fail the Activity Task.
In the latter case, the error is converted to an Application Failure.
Expand Down
42 changes: 0 additions & 42 deletions sample-apps/python/dynamic_handlers/your_dynamic_query_dacx.py

This file was deleted.

58 changes: 0 additions & 58 deletions sample-apps/python/dynamic_handlers/your_dynamic_signal_dacx.py

This file was deleted.

1 change: 1 addition & 0 deletions vale/styles/Temporal/terms.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ swap:
'\bworkflow\b': Workflow
timer: Timer
timers: Timers
update: Update
worker entity: Worker Entity
worker process: Worker Process
worker program: Worker Program
Expand Down