Skip to content

Reopen a condition wait with its remaining timeout, not the full timeout #245

Closed

Description

@rmcdaniel

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 full timeout_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_timeout TimerScheduled; a SignalReceived for an unrelated signal at 00:02 (workflow_sequence 1).
  • Result: replay emits [WaitCondition(timeout_seconds=300)].
  • Expected: timeout_seconds=180.

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.

Activity

  1. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    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):

    • 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.
    • PyPI 2.13.2 serves two files, both byte-identical (cmp) to the run's dist artifact:
      • wheel durable_workflow-2.13.2-py3-none-any.whl, 333,568 bytes, sha256 7d11bd98cee6e6e33466be0c61c6942bd4cf58378709cb271c60ec5882e26bd8;
      • sdist durable_workflow-2.13.2.tar.gz, 677,375 bytes, sha256 ef280b632198118c01f1eb6f11850d26cd56cf756915ea6ad40b1573ac462a73.
    • GitHub Release 2.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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:sdk-pythonWork by the sdk-python repo agentbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions