You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Reopen a condition wait with its remaining timeout, not the full timeout #245
Python counterpart of sdk-php#269 (a), found by sample-app's live runs. General has ruled on the PHP side: the deadline is fixed at the first open, and a reopen uses the remaining time.
Problem
ctx.wait_condition(predicate, key=..., timeout=300) opens a wait with timeout_seconds: 300 and a condition_timeout timer. When a signal arrives that leaves the predicate false, the worker re-drives the workflow, and the SDK reopens the wait with the fulltimeout_seconds again. Each signal that doesn't satisfy the predicate therefore pushes the timeout later. A "5 minute" approval window with a signal at +2m now times out at +7m.
Minimal replay on main 6076f30:
History: WorkflowStarted at 00:00; ConditionWaitOpened (seq 1, timeout_seconds 300) with its condition_timeoutTimerScheduled; a SignalReceived for an unrelated signal at 00:02 (workflow_sequence 1).
Existing tests encode the same pattern: in tests/test_wait_condition.py, each reopened ConditionWaitOpened carries timeout_seconds: 30 again.
Done when
A reopened wait for the same wait_condition call gets the remaining time: first ConditionWaitOpened.recorded_at + timeout - replay time of the re-drive, rounded up to whole seconds and never below 0. The deadline is fixed at the first open, matching embedded semantics.
A replay test and a regression-corpus fixture show the remaining time after a non-satisfying signal. The fixture must fail before the change and pass after it.
Existing in-flight histories that recorded the full timeout on reopen still replay. The server doesn't compare timeout_seconds, but this needs confirming with a corpus control.
Also check (b) from sdk-php#269: when replay shows a wait still open, the worker must not send a second open_condition_wait.
Owner: sdk-python, coordinated with sdk-php#269 so the two SDKs agree on rounding and on the replay time source.
Prepare Python SDK 2.13.2 #249 is merged at the cleared head 0abb51fc as 02bb33af816e27a6c9554f875e45a5ec748a0cf3, with parents main 1310272d and 0abb51fc. The merge tree 3a2af804 equals the head tree, and the merge carries version/product-train/registry-version 2.13.2.
The annotated tag 2.13.2 (object 916ca2a5) peels to 02bb33af.
Publisher: the tag push triggered publish.yml, run 41768578586, at exactly 02bb33af. That is the same trigger as 2.13.1, 2.13.0 and 2.12.4, so I didn't dispatch a second run. Its build, publish, verify and github-release jobs all succeeded.
PyPI2.13.2 serves two files, both byte-identical (cmp) to the run's dist artifact:
GitHub Release2.13.2 is not a draft or prerelease and targets main. releases/latest is 2.13.2.
Installed acceptance (lab2, arm64):
Setup: a fresh venv with pip install durable-workflow==2.13.2 from PyPI, run with python -I and no source tree. It ran against published native Server durableworkflow/server:3.0.5 (sha256:3cb6e5bf8ec766ac2abd933369b40a77af62794b6d7b921ce21d3fb263e88b72) in a disposable SQLite container, which has since been removed.
Workflow: wait_condition(..., timeout=20), with a non-satisfying signal at +6 s and another at +10 s.
SDK
Recorded ConditionWaitOpened.timeout_seconds
Result
Elapsed
2.13.2
20, 15, 11
timed-out
21.7 s (the deadline held at about 20 s)
2.13.1 (control, same script and server)
20, 20, 20
timed-out
30.3 s (each signal slid the deadline)
The two installed results bracket the fix on the real Server: 2.13.1 shows the bug and 2.13.2 doesn't.
Activity
Use the authored timeout and the sdk-php#269 clamp for reopens
rmcdaniel commentedon Nov 4, 2026
Python SDK 2.13.2 is published, and its installed-package acceptance passes. This release carries the fix for #245.
Release chain (General's go on #249):
0abb51fcas02bb33af816e27a6c9554f875e45a5ec748a0cf3, with parents main1310272dand0abb51fc. The merge tree3a2af804equals the head tree, and the merge carries version/product-train/registry-version 2.13.2.2.13.2(object916ca2a5) peels to02bb33af.publish.yml, run 41768578586, at exactly02bb33af. That is the same trigger as 2.13.1, 2.13.0 and 2.12.4, so I didn't dispatch a second run. Its build, publish, verify and github-release jobs all succeeded.cmp) to the run'sdistartifact:durable_workflow-2.13.2-py3-none-any.whl, 333,568 bytes, sha2567d11bd98cee6e6e33466be0c61c6942bd4cf58378709cb271c60ec5882e26bd8;durable_workflow-2.13.2.tar.gz, 677,375 bytes, sha256ef280b632198118c01f1eb6f11850d26cd56cf756915ea6ad40b1573ac462a73.releases/latestis 2.13.2.Installed acceptance (lab2, arm64):
pip install durable-workflow==2.13.2from PyPI, run withpython -Iand no source tree. It ran against published native Serverdurableworkflow/server:3.0.5(sha256:3cb6e5bf8ec766ac2abd933369b40a77af62794b6d7b921ce21d3fb263e88b72) in a disposable SQLite container, which has since been removed.wait_condition(..., timeout=20), with a non-satisfying signal at +6 s and another at +10 s.ConditionWaitOpened.timeout_secondsThe two installed results bracket the fix on the real Server: 2.13.1 shows the bug and 2.13.2 doesn't.