fix: assign new event IDs for activity retries and add TaskExecutionId#46
fix: assign new event IDs for activity retries and add TaskExecutionId#46
Conversation
Previously, retried activities reused the same event ID as the original attempt, diverging from durabletask-go, durabletask-java, and durabletask-dotnet which all assign a new sequence number per retry. This change aligns the Python SDK with the other SDKs by generating a new event ID for each retry attempt. Additionally, implements TaskExecutionId — a deterministic UUID that remains stable across all retry attempts of the same logical activity call, enabling idempotency and deduplication in activity execution. Signed-off-by: joshvanl <me@joshvanl.dev>
There was a problem hiding this comment.
Pull request overview
This PR aligns the Python SDK's activity retry behavior with durabletask-go, durabletask-java, and durabletask-dotnet by assigning a new sequence number (event ID) for each retry attempt instead of reusing the original event ID. It also introduces TaskExecutionId — a deterministic UUID that remains stable across retry attempts of the same logical activity call, enabling idempotency and deduplication.
Changes:
- Refactored
RetryableTaskto store task metadata (name, encoded input, instance ID, app ID, task execution ID) as instance fields instead of holding a reference to the protobuf action, and addedtask_execution_idtoActivityContext. - Updated retry logic in
_OrchestrationExecutor.process_eventandcall_activity_function_helperto generate new sequence numbers per retry and pass through the stabletask_execution_id. - Updated all retry-related tests to reflect the new ID numbering scheme and added
timerCreated/taskScheduledevents to test histories for proper replay fidelity.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
durabletask/task.py |
Replaced _action reference in RetryableTask with individual metadata fields; added task_execution_id property to ActivityContext. |
durabletask/worker.py |
Generate task_execution_id via new_guid() in call_activity; pass it through retry chain; use id=None on retries for new sequence numbers; pass taskExecutionId to ActivityContext. |
durabletask/internal/helpers.py |
Added task_execution_id parameter to new_schedule_task_action and set it on ScheduleTaskAction. |
tests/durabletask/test_orchestration_executor.py |
Updated all retry tests to expect new sequence numbers per retry attempt, added timerCreated/taskScheduled events, and verified updated error messages with correct task IDs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Signed-off-by: joshvanl <me@joshvanl.dev>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Previously, retried activities reused the same event ID as the original attempt, diverging from durabletask-go, durabletask-java, and durabletask-dotnet which all assign a new sequence number per retry. This change aligns the Python SDK with the other SDKs by generating a new event ID for each retry attempt.
Additionally, implements TaskExecutionId — a deterministic UUID that remains stable across all retry attempts of the same logical activity call, enabling idempotency and deduplication in activity execution.