Repository navigation
Declarative retry and backoff policies for action nodes (#86) - #225
Open
EricWittmann wants to merge 19 commits into
Open
EricWittmann wants to merge 19 commits into
EricWittmann wants to merge 19 commits into
Conversation
…ryAt on cancel (#86)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #86
Summary
Lets workflow authors declare retry and backoff policies on action nodes, with a workflow-level default,
instead of relying on the fixed engine policy (immediate retries, limit of 10).
config.retrywithmaxAttempts,delay,backoff(
fixed|exponential),multiplier,maxDelayandjitter. A workflow can setdefaults.retry.A node's policy replaces the default entirely; fields are not merged.
WorkflowErrorHandlerstill decides whether to retry; the policy decides how many timesand when. A zero delay retries immediately. A positive delay parks the node and records
retryAton theopen history entry. Attempt counts live on that entry (
attempt), so they survive asyncPENDINGresumes and persistence.
getPendingRetries(instance)lists parked retries; callretryNode(workflow, instance, nodeId)when your timer fires.retryNodedoes nothing for late, duplicate or cancelled timers.completeNodethrows for a node waiting to retry, andgetActionInforeturnsnullfor it.handleError(..., RetryContext)overload. Existing handlers are unaffected.INVALID_RETRY_*, plus aRETRY_ON_NON_ACTION_NODEwarning). Both run against a shared fixture,conformance/retry-validation.json, and the schema is updated.nodes show a
↻Nbadge. The viewer shows "Retry N/M scheduled at …" for a node waiting to retry.Backward compatibility
Definitions without a policy behave exactly as before: immediate retries, a limit of 10 and the same
failure message. New fields are optional and omitted from JSON when absent, and the old constructors are
kept. Callers that destructure
WorkfloworHistoryEntrywith Java record patterns will need updating,because both records gain components.
Testing
mvn test, 730 passing): inline and parked retries, exhaustion, workflow default vs nodeoverride, exponential backoff, jitter, attempt counts across async resumes, parallel fork/join retries,
cancel, and late timers.
vitest, 970 passing): validator parity with the shared fixture, retry helpers, the editorcommand and fields, and badges.
tsc,lint,buildandmkdocs build --strictall pass.exponential backoff with a decimal multiplier, and validation errors. The viewer's scheduled-retry status
is covered by unit tests only, because none of the demo scenarios has an instance waiting on a retry.
Follow-ups (not in this PR)
retryAtfor people in the viewer.Design spec:
docs/superpowers/specs/2026-10-21-declarative-retry-policy-design.md