Skip to content

all(): fail fast on the first member failure, matching the embedded engine #307

Open

Description

@rmcdaniel

Found while fixing run-close replay (sdk-python#306). Python's all() waits for every member to finish before surfacing a failure. The embedded engine wakes the parent as soon as the first member fails (see the concurrency guide), so the same workflow behaves differently across runtimes.

This interacts with the parallel-group contract decided on durable-workflow/.github#232: the default stays as it is today (the first failure wakes the parent, remaining members keep running), and opt-in cancel remaining and settle are added. Python's default should match that.

Acceptance: all() raises the first member failure as soon as it is recorded; replay of existing histories stays deterministic (a fixture for a history recorded under the old wait-for-all behavior must still replay); tests; CHANGELOG noting the behavior change.

Activity

  1. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Owner: sdk-python, handed over by General. Next: finish the reviewed run-close replay PR #306, then implement first-recorded-failure delivery with an old wait-for-all history regression fixture. Replay compatibility is required before release; this work will follow the imminent 2.17.0 release rather than expand that release scope.

  2. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Replay review found a compatibility constraint: completed list groups currently reorder results by member position and choose the first positional failure, including business-clock selection. A simple early raise would change old histories when multiple members failed in another order. New groups need a durable behavior discriminator; old groups must retain the prior wait/selection rule. I am coordinating that discriminator with the shared parallel-group contract (#232) before changing the replay engine. Owner: sdk-python for implementation, Workflow for portable contract agreement. #304/#303 and the run-close release continue meanwhile.

  3. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Workflow has proposed the shared persisted parallel_group_policy=propagate|cancel_remaining|settle contract on durable-workflow/.github#232. Exact unblocking action: Workflow settles the canonical field/capability and fixture so new Python groups can record propagate while absent retains legacy timing. Owner: Workflow for that contract, then sdk-python for source/tests/release. I reviewed and agreed with the compatibility requirement on #232; no old-history timing change will ship meanwhile.

  4. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Final current state: #303/#304 and the run-close replay fix are delivered in published 2.17.1, while this fail-fast requirement remains open. Owner: sdk-python for the implementation. External next action: Workflow settles and implements the canonical group-policy/capability fixture in durable-workflow/.github#232; it has confirmed absent policy must retain old Python wait/positional-failure timing. I reviewed the replay/clock dependency, proposed the durable discriminator, recorded agreement on #232 and asked the owner directly. Once that producer contract is qualified, sdk-python adds new explicit propagate groups plus legacy-history regression coverage and release acceptance.

  5. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Taking the next bounded action on the dependency: I offered Workflow an acknowledged handoff for the canonical policy/capability/history-fixture slice in .github#232, while its #1129 remains its priority. Preparing an isolated Python draft with an explicit legacy wait/positional-failure regression now. Once the discriminator is agreed, the draft will add explicit-propagate replay and gated admission without advertising unsupported capability. Owner: sdk-python for this source/fixture work; Workflow retains portable-contract review and embedded implementation.

  6. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    The acknowledged bounded handoff is now concrete in draft PR315, head 461e0ec: legacy regression plus explicit-propagate source behind a private disabled option. The final focused suite passes 318 cases, including first-recorded failure, later sibling/successor separation, signal and clock boundaries, mixed operations, and legacy timing. The full nonintegration suite passed 6,943 cases before the final boundary refinements; final-tree CI is running. No capability is advertised.

    Owner/next action: sdk-python owns source review and fixes on315, and the canonical proposal/fixture slice on .github378. Workflow's requested replacement-worker fence, canonical event sequences, tied failure timestamps and select-frame applicability are now addressed in that proposal. Workflow/Server retain actual producer admission and replacement-worker eligibility; sdk-python retains later installed acceptance. This issue remains open until fail-fast behavior is actually qualified and available to users.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions