Repository navigation
Name transport failures and local cancellation in worker logs and request metrics #167
Description
Delivered in Python SDK 2.10.0
Credential-safe poll diagnostics name exception classes and static routes, and request metrics distinguish local cancellation.
PyPI 2.10.0 is published at exact qualified source 4f853f396dba5a530ef0815509b16bfddaa9ebc3. Normal registry acceptance passes 334 controls, all 37 source files and all 50 hashed RECORD entries. Docs #212 merged at e530e33ec1303530779f91a0d249666c9f9aca16; its actual Pages deployment and all five affected routes were verified at 16:09 UTC. Current guidance states the minimum version.
Earlier failed observations remain failed. Separate #175/#215 source is outside this release.
Original report and earlier qualification
Current package delivery gate — October 23
The complete 2.10.0 candidate is 4f853f396dba5a530ef0815509b16bfddaa9ebc3, merged as 38b5a639262bebcf3fd0e67c6ec42ab16bc3a966 with the same tree. Fresh exact artifact hashes and installation proof: all 17 applicable normal gates, both distributions' smoke/metadata checks, 37 installed source/RECORD matches, 272 controls and actual console acceptance/refusal pass. The earlier 12b5f372 proof remains its own retained earlier cohort; the complete new candidate supersedes it only after all fresh proof passed.
Untagged and unpublished: existing #197 Trusted Publisher account setup remains required. No token fallback or repeated human account request. Actual registry installation and consumer acceptance remain open; draft #212 prepares versioned guidance and stays draft until those real delivery gates pass. Security-only 2.9.1/2da02a7a remains separate. No protocol-floor, major or automatic runtime/Cloud adoption follows.
Current source delivery — October 23
PR #211 merged normally at e31bc4efbc76d78ad9decf0c8e2b40e6b95b9369, with qualified candidate d6fe199bfb2a9a510b34751cab2072283ee8a7c3 names transport exception classes and static poll routes, preserves sanitized authentication summaries and bounded Server reasons, and records local CancelledError for ordinary and webhook-bridge request awaits, including cancellation during backoff. Cancellation still propagates immediately. Existing warning throttling, retries and durable budgets remain.
Tests-first 3ef90e1 has 11 failures / three passing existing-behavior controls on unchanged ffe79f5f. Current focused qualification has 382 pass / two existing skips in 16.01 seconds, plus Ruff and mypy on 37 source files. Full local qualification passes 3,390 / two existing skips / 105 integration deselections in 119.04 seconds. Normal CI 39947985508 and all 18 gates pass. Final Sonar is zero issues/unreviewed hotspots; CodeQL has no open alerts. Source delivery receipt preserves exact attribution and original failures. The shared-contract owner confirmed that CancelledError follows the existing language-specific exception convention; the SDK changelog announces the changed value, with no shared JSON revision.
The existing RemoteProtocolError retry is retained: actual Client controls prove stable poll ID, body, namespace, credentials and protocol header across a retry, bounded exhaustion, and immediate LocalProtocolError refusal. These are SDK unit/MockTransport observations, without a live-proxy claim. Request outcome and error guidance explicitly distinguishes local Python cancellation and durable outcomes. No shared metric name/tag/unit or protocol change.
This work follows the fixed, separately qualified 2.10.0 source candidate 12b5f3721e99afcfa37558dbcb78676d7bc49575; it is not included in that candidate's installed evidence. The diagnostics remain explicitly unreleased pending publication of the complete 2.10.0 candidate recorded above. Existing #197 Trusted Publisher setup still gates publication and normally installed registry acceptance. Website #267 remains consumer follow-through; no consumer delivery is assumed.
Python worker logs and request metrics do not let operators tell an intermediary disconnect or client timeout apart from a server refusal or a local cancellation.
Current behavior
Main 150c6f6bc14e3516f75cc615b2f75f093ed84ea1:
_poll_error_summaryreturnsstr(error)for anything that is not aServerError. Poll warnings log only that summary, with no exception class. httpx timeout and read errors can have an empty message, so the warning can name nothing.- The request metric starts with
outcome = "pending"and updates it only forException.asyncio.CancelledErroris not anException, so a request cancelled by shutdown or by the caller is recorded withoutcome="pending"andstatus_code="none". - The Python docs do not list the outcome values or say that transport failures surface as raw httpx exceptions after retries run out.
This was found by reading source and the pinned dependency code. It was not reproduced against a live proxy.
Expected
Poll and request failure logs always name the exception class and route. Local cancellation has an explicit documented outcome. The docs separate transport failures, durable activity or workflow cancellation, and asyncio.CancelledError.
Acceptance
- Unit tests: a message-less
ReadTimeoutorReadErrorproduces a warning that names the class, and server refusals keep their status and reason. - Cancelling an in-flight request records the documented cancellation outcome.
- Document the metric outcome values and the error categories.
- Decide whether to retry
RemoteProtocolErrorfor idempotent worker requests, document the decision and test it. - Link from durable-workflow.github.io#267.
Final target d6fe199b changes a test-only compatibility assumption: 14 current diagnostic controls pass in 0.50 seconds. The original CI 39947207526 failed four new Python 3.10 message-regex assertions (3,385 pass / three existing skips / 105 integration deselections); integration stayed skipped and target qualification refused as designed. Python documents cancellation-message propagation to the awaiter as new in 3.11. The test now asserts propagated CancelledError, actual cancelled-task state, unchanged single-request count and exact metrics on every supported version. Product code, timeout/skip/version floors and CI guards are unchanged. Functional parent 061a2ee owns the 3,390 full / 382 focused local results above; final CI 39947985508 and analyzer readback pass. The original failure is retained.
Activity
rmcdaniel commentedon Oct 23, 2026
Source delivery: PR #211 merged normally at
e31bc4efbc76d78ad9decf0c8e2b40e6b95b9369. Tree18158b0e19479df01349cee34ba20fce13fa1177matches qualified final candidated6fe199bfb2a9a510b34751cab2072283ee8a7c3. All 18 normal gates pass, including CI 39947985508. Final Sonar reports zero open/confirmed issues and zero unreviewed hotspots; CodeQL has no open alerts, with only runner notices. The merged remote head is deleted and independently verified absent.The functional
061a2eeparent passed 3,390 full local tests / two existing skips / 105 integration deselections in 119.04 seconds, and 382 focused controls. Final target changes only the test's supported-version assertion and passes all 14 new controls in 0.50 seconds, plus fresh full hosted Python 3.10/3.11/3.12 and integration gates. The original tests-first3ef90e1had 11 actual failures / three passing existing-behavior controls.Original CI 39947207526 remains failed: four new Python 3.10 assertions demanded cancellation-message propagation, which Python documents as new in 3.11. The corrected test verifies propagated cancellation, cancelled-task state, request count and metrics across every supported version. SDK product code, skip policy, deadlines and version/CI floors were unchanged by that correction. No original is called rescued.
Local cancellation now emits
CancelledErrorinstead ofpending, including retry backoff, while still propagating immediately. Poll warnings name classes and static routes without private transport messages. Existing credential redaction, Server reasons, throttling, retries and durable budgets remain. The shared-contract owner confirmed the language-specific exception convention; the changelog announces the value, without changing shared JSON/names/tags/units or Rust's distinct cancellation behavior.This is after, and not included in, the separately qualified 2.10.0 candidate
12b5f3721e99afcfa37558dbcb78676d7bc49575. The issue remains open for a subsequent qualified compatible package, normally installed registry acceptance and Website #267 follow-through. No tag/upload has been made while the existing #197 account setup is pending.rmcdaniel commentedon Oct 23, 2026
Delivered in Python SDK 2.10.0. Credential-safe poll diagnostics name exception classes and static routes, and request metrics distinguish local cancellation.
Registry acceptance and merged/deployed documentation #212 complete this acceptance. Current guidance is live. Earlier failed observations remain separate.