Add RetryConfig record for RetryMiddleware#150
Merged
Conversation
Replace RetryMiddleware's individual constructor kwargs with a single frozen RetryConfig (max_attempts / classifier / backoff / on_retry), constructed as RetryMiddleware(RetryConfig(...)). This is the shared record the upcoming call-level complete(retry=...) parameter will take, so one config serves both the per-node and per-call retry layers. The config fields are Optional and resolve to the canonical defaults (default_classifier / exponential_jitter_backoff) once in the consumer, preserving the prior None-means-default behavior so fixture-driven construction stays robust. Breaking change to the RetryMiddleware constructor; all call sites across tests, examples, and docs are migrated. First of two refactor PRs splitting proposal 0050's remaining work; call-level retry follows.
There was a problem hiding this comment.
Pull request overview
Refactors RetryMiddleware to consume a shared immutable RetryConfig record, aligning per-node retry configuration with the upcoming call-level retry API and migrating all internal call sites accordingly.
Changes:
- Introduces
RetryConfig(frozen dataclass) and updatesRetryMiddlewareto accept it (or default toRetryConfig()). - Migrates usages across tests, conformance harness builders, examples, and docs to
RetryMiddleware(RetryConfig(...)). - Updates public re-exports and changelog to reflect the breaking constructor change.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/test_observability_otel.py | Updates retry middleware construction to use RetryConfig. |
| tests/unit/test_observability_metadata.py | Updates retry middleware construction to use RetryConfig. |
| tests/unit/test_middleware.py | Migrates retry tests and adds basic RetryConfig validation/default tests. |
| tests/unit/test_fan_out.py | Updates retry middleware construction to use RetryConfig. |
| tests/unit/test_failure_isolation_middleware.py | Updates composed middleware example to use RetryConfig. |
| tests/conformance/test_pipeline_utilities.py | Updates middleware factory to build RetryConfig for RetryMiddleware. |
| tests/conformance/test_observability.py | Updates fixture-driven retry middleware creation to use RetryConfig. |
| src/openarmature/graph/middleware/retry.py | Adds RetryConfig and refactors RetryMiddleware to consume it. |
| src/openarmature/graph/middleware/init.py | Re-exports RetryConfig from openarmature.graph.middleware. |
| src/openarmature/graph/init.py | Re-exports RetryConfig from openarmature.graph. |
| examples/parallel-branches/main.py | Updates example to use RetryMiddleware(RetryConfig(...)). |
| examples/fan-out-with-retry/main.py | Updates example to use RetryMiddleware(RetryConfig(...)). |
| docs/concepts/middleware.md | Updates documentation examples and wording for RetryConfig. |
| CHANGELOG.md | Documents the breaking RetryMiddleware constructor change. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
From CoPilot review of PR #150: RetryMiddleware now takes a positional config, so a non-RetryConfig argument (e.g. RetryMiddleware(3)) would construct and then fail with a cryptic AttributeError at retry time. Raise TypeError eagerly in __init__ with the correct-usage idiom, and add a test.
This was referenced Jun 11, 2026
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.
Second PR in the proposal 0050 series (after #149 / FailureIsolationMiddleware). This is a pure refactor that prepares for call-level retry by making
RetryMiddlewareconsume a sharedRetryConfigrecord. The call-level retry feature itself (complete(retry=...)+ the in-call loop) follows in a third PR.What
RetryMiddleware's individual constructor kwargs are replaced by a single frozenRetryConfig(max_attempts/classifier/backoff/on_retry). Construct asRetryMiddleware(RetryConfig(max_attempts=...)); bareRetryMiddleware()still applies the defaults.This is the same record the upcoming call-level
complete(retry=...)parameter will accept, so a caller writes one retry config and uses it at either the per-node or the per-call layer.The config fields are Optional and resolve to the canonical defaults (
default_classifier/exponential_jitter_backoff) once in the consumer, preserving the prior None-means-default behavior. That keeps fixture-driven construction in the conformance harness robust (it passesNonefor unspecified settings) and makes every call-site migration a uniformRetryMiddleware(RetryConfig(...))wrap.Breaking change
The
RetryMiddleware(max_attempts=..., ...)kwargs constructor is removed. All call sites across the repo (tests, examples, docs) are migrated in this PR. No back-compat shim, by design.Scope
directives.py) is untouched: itsRetryMiddlewareis a Pydantic YAML model, not the real constructor; the real middleware is built in the migrated test bodies.Tests
Two new
RetryConfigtests (validation, default resolution) plus the migrated existing retry coverage. Full suite green (1261 passed), pyright and ruff clean, docs build clean.