Repository navigation
Show Python worker sessions in the guides #349
Description
Delivered
Delivered in PR #377, merge 3688a9d115d772b80b05cf35f8463b8c9eb0d200.
Final exact-head qualification, artifact deployment and actual Pages publication passed. All sixteen live Python/worker-session routes return HTTP 200 with correct canonical/alternate links. All eight actual session-guide links navigate to their localized Python recipe, and the Python table-of-contents link works. The live example includes typed options, both activities, worker capabilities, independent resource rebuilding and handled ActivityFailed. English, Japanese and Simplified Chinese 390px light/dark views were inspected with legible fonts and no document overflow.
See the Python recipe and shared lifecycle cross-link. Verified locales: English, Ukrainian, Spanish, Brazilian Portuguese, Simplified Chinese, Japanese, French and German.
The published-package receipt preserves normal reuse, actual killed-holder/rebuilt-state recovery and explicit-close/handled-timeout controls against Python 2.9.0 / Server 2.11.0 with the published maintenance role. All three fresh originals complete within unchanged 45-second bounds. The API-only failed original remains separately recorded; explicit close has two normal scheduled repair passes, not a claimed zero. No durable-memory, terminal-session reopening or immediate session-closed exception is promised. Completed runtime, raw databases and installed fixture dependencies are retired after public audit reconciliation.
Original report and acceptance
Problem
Python supports worker sessions, but no guide shows how to use them.
- The Python SDK exports
WorkerSessionOptions, andschedule_activitytakesworker_session=. - The affinity guide lists Python worker sessions as supported since 2.3.0.
- The worker sessions guide shows only PHP, and the Python guide never mentions sessions. Python users who need sequential activities on one worker, for example for local files, can't find the feature.
Acceptance criteria
- The worker sessions guide and the Python guide show a Python example: create the options, schedule several activities in one session, and handle the session ending or the worker being lost.
- The example is checked against the published Python SDK.
Activity
rmcdaniel commentedon Oct 21, 2026
Accepted as documentation for an existing Python capability. Check the options and session-loss behavior against the published SDK, then add runnable sequential activity examples to the worker-session and Python guides with parity in all seven translated locales and their source hashes.
If that published-package check exposes missing or incorrect session behavior, retain the failed example and open/link the product defect instead of documenting it as supported. No SDK feature or runtime acceptance is claimed by this intake. This follows the current security-release work.
rmcdaniel commentedon Oct 23, 2026
Taking the website implementation and published-package qualification. The product decision remains documentation for existing worker-session behavior. I will check Python SDK 2.9.0 against the published Server, preserve any failed originals, and add a runnable sequential-session recipe plus a concise cross-link from the embedded session guide in all eight locales. The recipe must show that worker-local state is disposable and must be rebuilt after holder loss; session affinity is not durable storage or transparent resource migration.
rmcdaniel commentedon Oct 23, 2026
Published-package qualification for the recipe in draft #377:
1e7547e895485dc8f670bd1b9cc34184b135f249db8da98b16b250bfc6002f73; its source identity was independently verified in SDK #186. The existing installed package was mounted read-only; no editable install or SDK source overlay.durableworkflow/server@sha256:b29157eb2cf844916debbbb3c01b3257672e0dece778a9c6fa539043a3038f02, SQLite / Python3.12 / amd64. Isolated internal network, no host ports or production access.ActivityTimedOut; the workflow catchesActivityFailedand completes withresource_unavailable. The session remains closed.The complete-role fixture uses the scheduler loop from the published 2.11.0 Compose recipe: schedule evaluation, repair pass, activity-timeout enforcement and history pruning, every10 seconds. The normal and holder-loss originals have zero repairs. The explicit-close original has two normal scheduled repair passes; they are recorded rather than reported as zero. There was no manual database write or special repair command outside the published scheduler role.
The first API-only fixture omitted that required role. Its normal and holder-loss controls passed, but the closed-session original did not become terminal within its original40-second observation bound and remained waiting beyond its45-second runtime deadlines. That failed observation is preserved, not relabeled by the new complete-role controls. The API-only database was stopped and frozen before the fresh database was created. A failed venv launcher and missing auth-driver setting occurred before workflow admission and are separate fixture errors.
Both current runtime processes are retired. API stopped0; the scheduler shell required termination after its10-second stop grace (137, no OOM). The final SELECT-only audit ran after both were stopped and preserves the database SHA256
f7fce5df896e1bb97c98dfb0a6ea61a3dd84da820f2b7b97c01caf4ed2f9db14. API-only snapshot SHA256a1bb5a1a940110357a66c16e50d3121227b8a5f0a4c3157afd0d5daa6971b608is separately preserved.Original results and read-only audit
{ "python": "2.9.0", "server": "2.11.0", "read_only_hash_preserved": true, "db_sha256": "f7fce5df896e1bb97c98dfb0a6ea61a3dd84da820f2b7b97c01caf4ed2f9db14", "originals": [ { "case": "normal", "run_id": "01m5m0y0sk7vnvz2rzresx7kvg", "status": "completed", "closed_at": "2026-10-23 09:19:40.527648", "run_deadline_at": "2026-10-23 09:20:21.754318", "execution_deadline_at": "2026-10-23 09:20:21.754318", "activity_attempts": [ { "activity_execution_id": "01m5m0y246c0a0yvc4htqfa5d9", "attempt_number": 1, "lease_owner": "website349-normal-a2644af1-reader", "status": "completed" }, { "activity_execution_id": "01m5m0y3crvahjn0zk3k0ptxhg", "attempt_number": 1, "lease_owner": "website349-normal-a2644af1-reader", "status": "completed" } ], "repair_count": 0, "events": [ "StartAccepted", "WorkflowStarted", "ActivityScheduled", "ActivityStarted", "ActivityCompleted", "ActivityScheduled", "ActivityStarted", "ActivityCompleted", "WorkflowCompleted" ], "output": { "status": "inspected", "prepared": { "holder": "website349-normal-a2644af1-reader", "rebuilt": true }, "inspected": { "holder": "website349-normal-a2644af1-reader", "rebuilt": false, "text": "document:website349-normal-a2644af1" } } }, { "case": "holder-loss", "run_id": "01m5m0y55s3pqbjrpza8y1rptq", "status": "completed", "closed_at": "2026-10-23 09:19:50.044843", "run_deadline_at": "2026-10-23 09:20:26.241050", "execution_deadline_at": "2026-10-23 09:20:26.241050", "activity_attempts": [ { "activity_execution_id": "01m5m0y6caj38z3c20pe29matp", "attempt_number": 1, "lease_owner": "website349-holder-loss-e8d9facb-holder", "status": "completed" }, { "activity_execution_id": "01m5m0y8qm5xme39r839v6cpqe", "attempt_number": 1, "lease_owner": "website349-holder-loss-e8d9facb-reader", "status": "completed" } ], "repair_count": 0, "events": [ "StartAccepted", "WorkflowStarted", "ActivityScheduled", "ActivityStarted", "ActivityCompleted", "ActivityScheduled", "ActivityStarted", "ActivityCompleted", "WorkflowCompleted" ], "output": { "status": "inspected", "prepared": { "holder": "website349-holder-loss-e8d9facb-holder", "rebuilt": true }, "inspected": { "holder": "website349-holder-loss-e8d9facb-reader", "rebuilt": true, "text": "document:website349-holder-loss-e8d9facb" } } }, { "case": "closed", "run_id": "01m5m0yeexeqs6mrkt02wh3pgd", "status": "completed", "closed_at": "2026-10-23 09:20:17.177913", "run_deadline_at": "2026-10-23 09:20:35.740211", "execution_deadline_at": "2026-10-23 09:20:35.740211", "activity_attempts": [ { "activity_execution_id": "01m5m0yfphynem3dadmf5k8zp8", "attempt_number": 1, "lease_owner": "website349-closed-8a7e142c-holder", "status": "completed" } ], "repair_count": 2, "events": [ "StartAccepted", "WorkflowStarted", "ActivityScheduled", "ActivityStarted", "ActivityCompleted", "ActivityScheduled", "ActivityTimedOut", "WorkflowCompleted" ], "output": { "status": "resource_unavailable", "job_id": "website349-closed-8a7e142c" } } ] }Reproducible fixture
Bootstrap a fresh database with the exact Server image,
DB_CONNECTION=sqlite,DB_DATABASE=/data/database.sqlite,DW_AUTH_DRIVER=noneandDW_WORKER_POLL_TIMEOUT=1. Authentication is disabled only inside this isolated, portless fixture. Run the API and the published singleton scheduler against that database. In a clean Python3.12 environment, normally installdurable-workflow==2.9.0, put the following files in/taskand runpython -u /task/probe.py. The probe's database access only observes the first completed activity through a read-only SQLite connection; all workflow/session mutations use SDK calls. Stop both Server roles beforepython /task/audit.py.example.py
probe.py
audit.py
Frozen API-only original observations
The following read-only snapshot retains the failed closed-session original and the two successful API-only controls. It is separate from complete-role acceptance. Raw fixture databases are retired after recording these hashes, observations and reproducible sources; no failed original is relabeled or reopened.
{ "db_sha256": "a1bb5a1a940110357a66c16e50d3121227b8a5f0a4c3157afd0d5daa6971b608", "hash_preserved": true, "runs": [ { "id": "01m5m0sgddadsknsa6c6wy9gmk", "status": "completed", "run_deadline_at": "2026-10-23 09:17:53.908688", "execution_deadline_at": "2026-10-23 09:17:53.908688", "closed_at": "2026-10-23 09:17:13.138364" }, { "id": "01m5m0snbbh49p9dgfne8dx5tv", "status": "completed", "run_deadline_at": "2026-10-23 09:17:58.963021", "execution_deadline_at": "2026-10-23 09:17:58.963021", "closed_at": "2026-10-23 09:17:21.960562" }, { "id": "01m5m0sy1ajxmx8gv6fcmrf690", "status": "waiting", "run_deadline_at": "2026-10-23 09:18:07.858257", "execution_deadline_at": "2026-10-23 09:18:07.858257", "closed_at": null } ], "activities": [ { "id": "01m5m0sjasbc41nhgyvkd69n6z", "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk", "activity_type": "prepare_document", "status": "completed", "attempt_count": 1, "schedule_to_close_deadline_at": "2026-10-23 09:17:30.871705" }, { "id": "01m5m0skfy7ansd6s4ftzbmksj", "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk", "activity_type": "inspect_document", "status": "completed", "attempt_count": 1, "schedule_to_close_deadline_at": "2026-10-23 09:17:32.061721" }, { "id": "01m5m0spqe9bykcs7vvk89agcj", "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv", "activity_type": "prepare_document", "status": "completed", "attempt_count": 1, "schedule_to_close_deadline_at": "2026-10-23 09:17:35.374060" }, { "id": "01m5m0srte260rm68xfkpc8gc2", "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv", "activity_type": "inspect_document", "status": "completed", "attempt_count": 1, "schedule_to_close_deadline_at": "2026-10-23 09:17:37.518061" }, { "id": "01m5m0sz4krpatd38ethpb3pn3", "workflow_run_id": "01m5m0sy1ajxmx8gv6fcmrf690", "activity_type": "prepare_document", "status": "completed", "attempt_count": 1, "schedule_to_close_deadline_at": "2026-10-23 09:17:43.986724" }, { "id": "01m5m0t1ke53hawq741wpjpvkw", "workflow_run_id": "01m5m0sy1ajxmx8gv6fcmrf690", "activity_type": "inspect_document", "status": "pending", "attempt_count": 0, "schedule_to_close_deadline_at": "2026-10-23 09:17:46.509846" } ], "tasks": [ { "id": "01m5m0sgm1n81k20qjr7yxqgsp", "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk", "repair_count": 0, "status": "completed" }, { "id": "01m5m0sjbf98k5jzdswdgwbybk", "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk", "repair_count": 0, "status": "completed" }, { "id": "01m5m0sk36efrr1mr68ssc3g6y", "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk", "repair_count": 0, "status": "completed" }, { "id": "01m5m0skg3w64jwckddgq0s7jj", "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk", "repair_count": 0, "status": "completed" }, { "id": "01m5m0sm3pr48njjv69c5ygw8r", "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk", "repair_count": 0, "status": "completed" }, { "id": "01m5m0snbpq8pvzdkffyw7mw48", "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv", "repair_count": 0, "status": "completed" }, { "id": "01m5m0spqmgb73ve0szg5cwjxm", "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv", "repair_count": 0, "status": "completed" }, { "id": "01m5m0srafjwrkfpy9zy9bef92", "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv", "repair_count": 0, "status": "completed" }, { "id": "01m5m0srtpnywf7n674h64y3s7", "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv", "repair_count": 0, "status": "completed" }, { "id": "01m5m0swkgzr6dk8ycsdce9ha6", "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv", "repair_count": 0, "status": "completed" }, { "id": "01m5m0sy1t3fasza3heeyvxwcf", "workflow_run_id": "01m5m0sy1ajxmx8gv6fcmrf690", "repair_count": 0, "status": "completed" }, { "id": "01m5m0sz4tqa6pavte9vd5b7d3", "workflow_run_id": "01m5m0sy1ajxmx8gv6fcmrf690", "repair_count": 0, "status": "completed" }, { "id": "01m5m0t0zw9z0pe9e6eanqqg2q", "workflow_run_id": "01m5m0sy1ajxmx8gv6fcmrf690", "repair_count": 0, "status": "completed" }, { "id": "01m5m0t1kmph9sjnwsqb7wgjmq", "workflow_run_id": "01m5m0sy1ajxmx8gv6fcmrf690", "repair_count": 0, "status": "ready" } ], "session_tables": [ "workflow_worker_sessions" ] }rmcdaniel commentedon Oct 23, 2026
Delivered in PR #377, merge
3688a9d115d772b80b05cf35f8463b8c9eb0d200.Final exact-head qualification, artifact deployment and actual Pages publication passed. All sixteen live Python/worker-session routes return HTTP 200 with correct canonical/alternate links. All eight actual session-guide links navigate to their localized Python recipe, and the Python table-of-contents link works. The live example includes typed options, both activities, worker capabilities, independent resource rebuilding and handled
ActivityFailed. English, Japanese and Simplified Chinese 390px light/dark views were inspected with legible fonts and no document overflow.See the Python recipe and shared lifecycle cross-link. Verified locales: English, Ukrainian, Spanish, Brazilian Portuguese, Simplified Chinese, Japanese, French and German.
The published-package receipt preserves normal reuse, actual killed-holder/rebuilt-state recovery and explicit-close/handled-timeout controls against Python 2.9.0 / Server 2.11.0 with the published maintenance role. All three fresh originals complete within unchanged 45-second bounds. The API-only failed original remains separately recorded; explicit close has two normal scheduled repair passes, not a claimed zero. No durable-memory, terminal-session reopening or immediate session-closed exception is promised. Completed runtime, raw databases and installed fixture dependencies are retired after public audit reconciliation.