github durable-workflow/workflow 2.19.0

2 hours ago

Failed-run redrive recovers more workflows: workflow-code memo and search-attribute upserts, applied signal waits, and failures in workflow code, including onto a corrected definition when you ask for it.

Redrive (#864)

  • Workflow-code upserts (#1001): MemoUpserted and SearchAttributesUpserted steps in the completed prefix are reused at their original time. Memo and search-attribute rows carry to the successor unchanged, so a successor that fails again can be redriven again.
  • Applied signal waits (#1002): a signal wait (await('name')) that received and applied its signal is reused with its value and original time. The message cursor carries over, so a consumed signal isn't delivered again.
  • Workflow-code and structural-limit failures (#1004): WorkflowFailed now records failed_step_sequence with failed_step_kind workflow_code or structural_limit, and the successor resumes at that step.
    • On the same definition, a workflow-code failure is refused, because the same code would throw again. A structural-limit failure may redrive.
  • Corrected definition, opt-in only (#1004): pass allow_definition_change: true.
    • Inside the redrive transaction, the new code replays the reused prefix in memory, bounded by the history budget, before anything is written.
    • An accepted change records definition_changed_from on the successor's WorkflowStarted. Run detail shows it as workflow_definition_changed_from, and describe as run.definition_changed_from. A later redrive on the same definition records none.

Upgrade notes

  • Rollback. Releases before 2.19.0 ignore reused_recorded_at on the signal, memo and search-attribute events that a 2.19.0 redrive successor reuses. Replaying such a successor on an older release can change its workflow time and the deadlines derived from it. Once a 2.19.0 redrive successor with reused signal waits or upserts exists, keep 2.19.0 or later workers, or confirm that no such history can replay before rolling back.

  • New failed_step_kind values. workflow_code and structural_limit join activity. Readers that switch on failed_step_kind should accept them. Failures written by earlier releases have no boundary and still refuse redrive with unrecorded_failure_boundary.

  • allow_definition_change is an explicit opt-in. Without it, a changed definition is refused as before. Runs started by a service worker are always refused with definition_change_requires_replay_check, even if a local class is registered for the type later.

  • New typed refusals:

    • workflow_code_failure_requires_corrected_definition
    • definition_incompatible_with_prefix, with definition_mismatch {sequence, kind}
    • definition_check_over_budget
    • definition_change_requires_replay_check
    • unsupported_signal_wait, unsupported_pending_signal, incomplete_signal_step, mismatched_signal_receipt, external_signal_payload_not_supported
    • service_redrive_history_not_qualified

    unsupported_visibility_metadata now refuses only a workflow-code row with no matching reused upsert step.

  • Service mode (#1006):

    • A run a service worker started is refused redrive with service_redrive_history_not_qualified when its completed prefix has a memo upsert, search-attribute upsert or signal wait to reuse. The refusal happens before any write. The fence lifts only through a replay-capability check once durable-workflow/sdk-python#235, durable-workflow/sdk-php#244 and durable-workflow/sdk-rust#172 ship installed-qualified.
    • Service runs whose prefix holds only activities, side effects, version markers and fired timers redrive as in 2.18.0. That SDK replay is qualified: Python 2.13.1 and PHP 3.8.3 installed-qualified, Rust 4.11.0 last fully qualified, with Rust's lifecycle open in durable-workflow/sdk-rust#170.
    • Native Server redrive parity is still open in durable-workflow/server#980.

Main CI was green at 28893f97 (merge of #1005). Release Verification runs on this tag.

Don't miss a new workflow release

NewReleases is sending notifications on new releases.