Skip to content

Commit ff41a37

Browse files
docs(2275): remove non-existent RetryConfig.Builder methods from README [skip-runtime-e2e] (#180)
The README's 'Retry Configuration' section advertised three RetryConfig.Builder methods that do not exist in the public API: - initialDelayMs(int) — actual Builder has initialDelay(Duration) - maxDelayMs(int) — actual Builder has maxDelay(Duration) - retryableStatusCodes(Set<Integer>) — does not exist at all; the retry policy is hard-coded in RetryExecutor.isRetryable (5xx + 429 + connect/timeout, with 401/403/PolicyViolation/Config exceptions always terminal) The third method was the most load-bearing in the #2275 context. A user reading the README would expect to be able to configure which statuses retry. If they looked for the method and didn't find it, they might write a workaround that bypassed retryExecutor entirely, reintroducing the storm that PR #178 added regression coverage for. Decision: delete the misleading example, not implement the methods. Implementing retryableStatusCodes would be a feature addition (a new configuration surface + serialized semantics + tests), not a doc fix. This PR replaces the offending block with: - one paragraph documenting the ACTUAL retry contract from RetryExecutor.isRetryable - a citation back to #2275 (the regression test from PR #178 locks in that 401 stays terminal) - a list of every Builder method that ACTUALLY exists (enabled, maxAttempts, initialDelay, maxDelay, multiplier) with default values - a working example using initialDelay(Duration.ofMillis(100)) / maxDelay(Duration.ofSeconds(5)) so the code-block compiles against the real API CHANGELOG entry under [Unreleased] notes this is a documentation-only fix — no public-API or behavior change. Lineage: - Hostile review of PR #178 (regression test for issue #2275) flagged this as HIGH doc-debt. PR #178 author punted. - This follow-up PR closes the finding. Out of scope: - Adding retryableStatusCodes or any per-status configuration to the Builder (that's a feature). - Changing RetryExecutor.isRetryable behavior. - Version bump. Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
1 parent 6778902 commit ff41a37

2 files changed

Lines changed: 36 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@ All notable changes to the AxonFlow Java SDK will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased]
9+
10+
### Fixed
11+
12+
- **README "Retry Configuration" section.** Removed three `RetryConfig.Builder`
13+
methods that do not exist on the public API (`initialDelayMs(int)`,
14+
`maxDelayMs(int)`, `retryableStatusCodes(Set<Integer>)`). The example now
15+
uses the actual `initialDelay(Duration)` / `maxDelay(Duration)` builders, and
16+
the surrounding prose documents the real retry contract from
17+
`RetryExecutor.isRetryable`: retries fire on connect/timeout, `5xx`, and
18+
`429`; `401`/`403` and other `4xx` are always terminal. Locked in by the
19+
regression test added for
20+
[getaxonflow/axonflow-enterprise#2275](https://github.com/getaxonflow/axonflow-enterprise/issues/2275)
21+
in PR #178. Documentation-only — no code or behavior change.
22+
823
## [8.1.0] - 2026-05-19 — `X-Client-ID` header on every outbound request (v9 identity)
924

1025
**Companion release to the v9 identity cleanup on the platform (Epic #2230).**

README.md

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,19 +337,35 @@ try {
337337

338338
## Retry Configuration
339339

340-
The SDK includes automatic retry with exponential backoff:
340+
The SDK includes automatic retry with exponential backoff. The retry policy
341+
itself is not configurable per HTTP status — retries fire on connect/timeout
342+
errors, `5xx` server errors, and `429 Too Many Requests`. Authentication
343+
failures (`401`/`403`), policy violations, and other `4xx` client errors are
344+
always terminal and never retried (see `RetryExecutor.isRetryable`). This
345+
contract is locked in as a regression test for
346+
[getaxonflow/axonflow-enterprise#2275](https://github.com/getaxonflow/axonflow-enterprise/issues/2275)
347+
— a retry storm on `401` against a misconfigured agent.
348+
349+
The `RetryConfig.Builder` exposes the following knobs:
350+
351+
- `enabled(boolean)` — turn retries off entirely (defaults to `true`).
352+
- `maxAttempts(int)` — total attempts including the first, `1``10` (default `3`).
353+
- `initialDelay(Duration)` — base delay before the second attempt (default `1s`).
354+
- `maxDelay(Duration)` — cap on the exponential backoff (default `30s`).
355+
- `multiplier(double)` — backoff multiplier, ≥ `1.0` (default `2.0`).
341356

342357
```java
358+
import java.time.Duration;
359+
343360
AxonFlowConfig config = AxonFlowConfig.builder()
344361
.endpoint("https://agent.getaxonflow.com")
345362
.clientId("your-client-id")
346-
.clientSecret("your-client-secret")
363+
.clientSecret("your-client-secret")
347364
.retryConfig(RetryConfig.builder()
348365
.maxAttempts(3)
349-
.initialDelayMs(100)
350-
.maxDelayMs(5000)
366+
.initialDelay(Duration.ofMillis(100))
367+
.maxDelay(Duration.ofSeconds(5))
351368
.multiplier(2.0)
352-
.retryableStatusCodes(Set.of(429, 500, 502, 503, 504))
353369
.build())
354370
.build();
355371
```

0 commit comments

Comments
 (0)