From ef6040cef93ad8ec267f9e5888233a8027cf7498 Mon Sep 17 00:00:00 2001 From: Durable Workflow Date: Tue, 6 Oct 2026 08:13:59 +0000 Subject: [PATCH 1/3] Document stable Server cooperative cancellation --- docs/polyglot/cancellation.md | 6 +++--- .../worker-protocol-api.openapi.yaml | 6 +++--- .../worker-protocol-stream.asyncapi.yaml | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/polyglot/cancellation.md b/docs/polyglot/cancellation.md index 2197733ddb..b89c4c7466 100644 --- a/docs/polyglot/cancellation.md +++ b/docs/polyglot/cancellation.md @@ -5,8 +5,8 @@ description: Request bounded cleanup across a workflow, its children and its act # Cooperative cancellation -Protocol 1.20 adds cooperative cancellation to the self-hosted Server release -candidate. It requires workers that explicitly enable cooperation. Check runtime +Server 2.5.0 adds cooperative cancellation through protocol 1.20. It requires +workers that explicitly enable cooperation. Check runtime discovery and the SDK's capability support before using it. ## Request cleanup @@ -89,7 +89,7 @@ registration does not upgrade a claim that was already issued. ## Release boundary Whole-run requests, child and activity policies, bounded shielded cleanup, -recovery and cascade inspection form this release candidate. Independently +recovery and cascade inspection form the supported release. Independently cancellable operation scopes remain a disabled source preview and are marked experimental in the protocol reference. diff --git a/static/platform-protocol-specs/worker-protocol-api.openapi.yaml b/static/platform-protocol-specs/worker-protocol-api.openapi.yaml index 63cbbbefad..3da1eb0622 100644 --- a/static/platform-protocol-specs/worker-protocol-api.openapi.yaml +++ b/static/platform-protocol-specs/worker-protocol-api.openapi.yaml @@ -1,7 +1,7 @@ openapi: 3.1.0 info: title: durable-workflow.v2.worker-protocol-api - version: "47" + version: "48" summary: Durable Workflow worker-plane HTTP+JSON API description: > Normative OpenAPI specification for the worker-plane HTTP+JSON API: @@ -56,7 +56,7 @@ x-durable-workflow-cancellation-scope-opening: allowance: shares_existing_workflow_claim_budget replay: identical_parent_and_shield_reuses_canonical_history_identity x-durable-workflow-cooperative-cancellation-contract: - status: release_candidate + status: stable minimum_protocol_version: "1.20" worker_capability: cooperative_cancellation request_operation: POST /workflows/{workflowId}/request-cancellation @@ -91,7 +91,7 @@ x-durable-workflow-cooperative-cancellation-contract: cleanup_completion: cancelled_with_original_request_id terminal_cancel_and_terminate: unchanged x-durable-workflow-prepared-local-activity-contract: - status: release_candidate + status: stable minimum_protocol_version: "1.20" worker_capabilities: [cooperative_cancellation, prepared_local_activities] backend_role: Workflow\V2\Contracts\PreparedLocalActivityTaskBridge diff --git a/static/platform-protocol-specs/worker-protocol-stream.asyncapi.yaml b/static/platform-protocol-specs/worker-protocol-stream.asyncapi.yaml index d43007949c..845433176e 100644 --- a/static/platform-protocol-specs/worker-protocol-stream.asyncapi.yaml +++ b/static/platform-protocol-specs/worker-protocol-stream.asyncapi.yaml @@ -2,7 +2,7 @@ asyncapi: 2.6.0 id: durable-workflow.v2.worker-protocol-stream info: title: Durable Workflow worker-protocol long-poll stream semantics - version: "14" + version: "15" description: > Normative AsyncAPI description of the public worker-protocol stream semantics. Durable uses HTTP long-poll request/response rather than a @@ -226,7 +226,7 @@ components: properties: protocol_version: type: string - const: "1.19" + const: "1.20" server_capabilities: type: object additionalProperties: true From 7985e7463fba3deac802f96e833677269b83dfde Mon Sep 17 00:00:00 2001 From: Durable Workflow Date: Tue, 6 Oct 2026 08:46:00 +0000 Subject: [PATCH 2/3] Publish the qualified stable cancellation tuple --- static/stable-releases.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/static/stable-releases.json b/static/stable-releases.json index fd5894f481..a30af21d4a 100644 --- a/static/stable-releases.json +++ b/static/stable-releases.json @@ -4,11 +4,11 @@ "updated_at": "2026-10-06", "artifacts": { "cli": "2.2.0", - "sdk-php": "2.1.0", - "sdk-python": "2.1.0", - "sdk-rust": "2.1.0", - "server": "2.4.0", - "waterline": "2.0.4", - "workflow": "2.1.1" + "sdk-php": "2.2.0", + "sdk-python": "2.4.0", + "sdk-rust": "3.0.0", + "server": "2.5.0", + "waterline": "2.1.0", + "workflow": "2.4.0" } } From 58284c9863a8de9cd85b2dd5a2546cef18dd93db Mon Sep 17 00:00:00 2001 From: Durable Workflow Date: Tue, 6 Oct 2026 08:47:58 +0000 Subject: [PATCH 3/3] Align service guides with shipped cooperative cancellation --- docs/polyglot/php.md | 4 ++++ docs/polyglot/portable-worker-affinity.md | 17 +++++++++++------ docs/polyglot/python.md | 7 ++++--- docs/polyglot/rust.md | 8 ++++---- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/docs/polyglot/php.md b/docs/polyglot/php.md index 43d4ae8859..df106b9bee 100644 --- a/docs/polyglot/php.md +++ b/docs/polyglot/php.md @@ -134,6 +134,10 @@ The current public client is broader than selected-run result handling: - `Client` exposes `listWorkflows` with server filtering and pagination, `workflowHistory`, `updateWorkflow`, `cancelWorkflow`, and `terminateWorkflow`. +- `requestCancellation()` requests bounded cleanup from cooperating workers. + Existing `cancel()` and `cancelWorkflow()` close the run immediately. See + [cooperative cancellation](/docs/polyglot/cancellation) for the authoring and + recovery contract. - Schedule methods cover create, describe, list, update, pause, resume, trigger, backfill, and delete. - Operational visibility includes `listNamespaces`, `listWorkers`, and diff --git a/docs/polyglot/portable-worker-affinity.md b/docs/polyglot/portable-worker-affinity.md index 1bb465247f..830f0f3c0f 100644 --- a/docs/polyglot/portable-worker-affinity.md +++ b/docs/polyglot/portable-worker-affinity.md @@ -43,12 +43,17 @@ server records that sequence atomically as normal activity history marked `execution_mode=local`. Replay consumes the recorded terminal activity event. It does not invoke the -local handler again. The synchronous PHP handler is not preempted: cancellation -and elapsed heartbeat, per-attempt, and total timeouts are observed before an -attempt, when the handler calls `ActivityContext::heartbeat()`, or after the -handler returns. A handler that neither returns nor heartbeats cannot be -interrupted by these cooperative controls, so local activities must remain -short and divide blocking work with safe heartbeat boundaries. +local handler again. Ordinary PHP workers execute the synchronous handler +inline. Cancellation and elapsed heartbeat, per-attempt, and total timeouts +are observed before an attempt, at `ActivityContext::heartbeat()`, or after the +handler returns. These handlers must remain short and divide blocking work +with safe heartbeat boundaries. + +Workers that enable [cooperative cancellation](/docs/polyglot/cancellation) +use protocol 1.20 and supervised callback processes for prepared local +activities. They observe cancellation and stop the callback independently of +application heartbeats. Durable stop receipts and attempt fencing distinguish +callback stop from refusal of a late result. ## Worker session lifecycle diff --git a/docs/polyglot/python.md b/docs/polyglot/python.md index 835dead5ec..361109051f 100644 --- a/docs/polyglot/python.md +++ b/docs/polyglot/python.md @@ -402,9 +402,10 @@ when a script already knows the workflow id and wants handle-style methods. Both operations close the Server run immediately with distinct terminal outcomes. `cancel_workflow` does not deliver a cooperative request to workflow -code or run saga/finally cleanup. Arrange cleanup before terminal cancellation -or use external reconciliation; embedded Laravel's `requestCancellation()` is -a separate capability, not yet available in service mode. +code or run saga/finally cleanup. Use `request_cancellation()` with cooperating +workers for bounded workflow cleanup. See the +[cooperative cancellation guide](/docs/polyglot/cancellation) for operation +policies, supervision and recovery. ### Schedules diff --git a/docs/polyglot/rust.md b/docs/polyglot/rust.md index 0d67c851e4..527c430adc 100644 --- a/docs/polyglot/rust.md +++ b/docs/polyglot/rust.md @@ -371,10 +371,10 @@ drained. See [Side Effects](/docs/features/side-effects/) and Service-mode `cancel_workflow` and `terminate_workflow` both close the run immediately. They record distinct terminal outcomes, but neither asks workflow -code to run cleanup. Arrange compensation before closing the run or use external -reconciliation. Embedded Laravel has a separate cooperative -`requestCancellation()` capability; Server and service-mode SDKs do not yet -expose that request. +code to run cleanup. Use `request_cancellation()` with cooperating workers for +bounded workflow cleanup. See the +[cooperative cancellation guide](/docs/polyglot/cancellation) for operation +policies, supervision and recovery. ```rust use durable_workflow::{Client, WorkflowCommandOptions};