Skip to content

fix: Non-default HTTP retry backoff strategies cannot be selected - #6529

Open
hengyuss wants to merge 10 commits into
apache:masterfrom
hengyuss:fix/Non_default_HTTP_retry_backoff_strategies_cannot_be_selected
Open

fix: Non-default HTTP retry backoff strategies cannot be selected#6529
hengyuss wants to merge 10 commits into
apache:masterfrom
hengyuss:fix/Non_default_HTTP_retry_backoff_strategies_cannot_be_selected

Conversation

@hengyuss

@hengyuss hengyuss commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Fixes #6464

Make sure that:

  • You have read the contribution guidelines.
  • You submit test cases (unit or integration tests) that back your changes.
  • Your local test passed ./mvnw clean install -Dmaven.javadoc.skip=true.

- Add HttpRetryBackoffSpecEnumTest for acquireByName coverage
- Add retryBackOffSpec getter/setter test in DivideRuleHandleTest
- Add DividePluginTest assertions for HTTP_RETRY_BACK_OFF_SPEC attribute
- Fix plugin_handle sort conflict: retryBackOffSpec sort 0→1
- Disable custom dict entry (enabled 1→0) in all SQL dialects
- Remove CUSTOM_BACKOFF enum value and CustomRetryStrategy class
- Remove CUSTOM_BACKOFF case from AbstractHttpClientPlugin switch
@hengyuss
hengyuss force-pushed the fix/Non_default_HTTP_retry_backoff_strategies_cannot_be_selected branch from 8d985ef to 432de3b Compare August 2, 2026 11:15

@Aias00 Aias00 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed #6529 — fixes #6464. The root-cause analysis is correct and the fix is sound: Constants.HTTP_RETRY_BACK_OFF_SPEC was "default", used as the exchange attribute key, so nothing ever wrote under it and AbstractHttpClientPlugin always fell back to DefaultRetryStrategy, leaving fixed/exponential/custom unreachable. Renaming the key to "httpRetryBackOffSpec", adding DivideRuleHandle.retryBackOffSpec, populating it in DividePlugin, switching the switch to HttpRetryBackoffSpecEnum, and replacing CustomRetryStrategy's return null with an explicit Mono.error all address the reported defects. Backward compatibility is fine: existing rule-handle JSON lacks the new field, Gson leaves it at the field initializer ("default"), so existing configs keep routing to DefaultRetryStrategy. DB IDs are collision-free and consistent across all 6 init dialects and 5 upgrade scripts. The constant-value change only affects an in-memory attribute key (no persisted JSON key changes; only 3 Java consumers).

Non-blocking, but worth addressing before merge:

  1. (should_fix) No regression test for the actual bug. DivideRuleHandleTest.testGetterSetter covers every sibling field except retryBackOffSpec; DividePluginTest doesn't assert Constants.HTTP_RETRY_BACK_OFF_SPEC is placed into the exchange from ruleHandle.getRetryBackOffSpec(); RetryStrategyTest exercises strategies in isolation but not the selection switch in AbstractHttpClientPlugin.execute. The whole point of the PR — that a configured non-default spec is actually selected — is untested, so #6464 can regress silently. Suggested additions: (a) a DividePluginTest case asserting the attribute is set from the rule handle (mirroring the HTTP_RETRY/RETRY_STRATEGY puts); (b) HttpRetryBackoffSpecEnumTest covering acquireByName for each name + null + unknown → DEFAULT_BACKOFF (every other enum in the package has one); (c) extend testGetterSetter to set/assert retryBackOffSpec.

  2. (nit) The new retryBackOffSpec plugin_handle row uses sort=0, identical to retryStrategy, so the two fields' admin-UI order is non-deterministic. Give it a distinct sort (e.g. 1).

  3. (nit / open question) CustomRetryStrategy now throws UnsupportedOperationException("Please implement CustomRetryStrategy via SPI"). Returning an explicit error is a clear improvement over return null, but I couldn't find an SPI/registry for this strategy in the diff or under shenyu-plugin-httpclient. If no extension point exists, consider hiding custom from the RETRY_BACKOFF_SPEC dict until one does, since selecting it today always yields a 503.

Note: PR is in BEHIND merge state (needs a rebase onto master before merge).

@Aias00

Aias00 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Solid, well-tested fix — the string→enum switch in AbstractHttpClientPlugin is cleaner, acquireByName gracefully falls back to DEFAULT_BACKOFF for null/empty/unknown (covered by HttpRetryBackoffSpecEnumTest), and DivideRuleHandle.equals/hashCode/toString are correctly updated (plus a nice toString comma fix). Removing CustomRetryStrategy is safe — it was a stub whose execute(...) returned null, and the only caller (AbstractHttpClientPlugin:94) is rewritten in this PR; no other references remain. Backward compat looks fine: existing rules without retryBackOffSpec deserialize to the field default "default", which matches the pre-PR behavior (the attribute was previously null → Optional.orElse(getDefault())DefaultRetryStrategy).

One minor inconsistency: the SQL scripts add a custom dict entry ('custom','custom','custom',3,0, enabled=0) across all dialects, but HttpRetryBackoffSpecEnum no longer has CUSTOM_BACKOFF (removed in this PR). So custom is now a dead/disabled dict value — acquireByName("custom") falls through to DEFAULT_BACKOFF. Since the entry is enabled=0 it won't surface in the admin UI, so there's no runtime impact, but you could either drop the custom dict rows or keep the enum value to avoid the mismatch. Just flagging.

hengyuss and others added 3 commits August 5, 2026 23:58
…ff_strategies_cannot_be_selected' into fix/Non_default_HTTP_retry_backoff_strategies_cannot_be_selected
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Non-default HTTP retry backoff strategies cannot be selected

2 participants