Skip to content

feat: isolate dual-registration failure handling per mode#16248

Open
ban-xiu wants to merge 4 commits intoapache:3.3from
ban-xiu:feat-dual-reg
Open

feat: isolate dual-registration failure handling per mode#16248
ban-xiu wants to merge 4 commits intoapache:3.3from
ban-xiu:feat-dual-reg

Conversation

@ban-xiu
Copy link
Copy Markdown

@ban-xiu ban-xiu commented Apr 28, 2026

What is the purpose of the change?

Close #16247.

Problem

In dual registration mode (register-mode=all) Dubbo emits a single provider URL through two registries:
- interface-level -> registry:// (ZooKeeper, Nacos, ...) - instance-level -> service-discovery-registry://

RegistryProtocol#export calls register() once; the registry wrapper
fans out to both arms. Any RuntimeException from the first arm aborts
the second, so a transient failure on the metadata center silently
takes down the interface-level registration that was otherwise healthy
(or vice versa). The pre-existing FrameworkStatusReportService only
reports a coarse "instance/interface" status and cannot tell observers
which arm failed, which swallowed the error, or why.

Fix

  1. FrameworkStatusReportService

    • add reportRegistrationOutcome(mode, registryAddress, serviceKey,
      success, errorMessage) + createRegistrationOutcomeReport() so each
      registration attempt emits an independently tagged payload
      {application, mode, registry, service, status, error?}.
  2. RegistryProtocol

    • new registerWithModeTag(registry, registryUrl, providerUrl) wraps
      the existing register() call with per-arm failure isolation:
      • success -> report SUCCESS tagged with the resolved mode
      • RuntimeException:
        • report FAILED with the cause message
        • honor registryUrl check= parameter: rethrow iff check=true,
          otherwise log a warn under CONFIG_REGISTER_INSTANCE_ERROR
          (5-11) and return false so the sibling arm keeps going
    • resolveRegisterModeTag() centralizes the INTERFACE_REGISTER vs
      INSTANCE_REGISTER label (previously hardcoded in one log line).
    • route export() and ExporterChangeableWrapper.register() through
      the new wrapper; replace the hardcoded "[INSTANCE_REGISTER]" log
      prefix with the resolved tag.
    • reporting failures never leak into the registration flow
      (wrapped in try/catch(Throwable)).

Tests

  • dubbo-common: FrameworkStatusReportServiceTest gains
    testReportRegistrationOutcomeSuccess / Failure covering the new
    payload shape.
  • dubbo-registry-api: new RegistryProtocolDualRegisterTest with 4
    reflection-driven cases over registerWithModeTag — success paths for
    both protocols, check=true rethrow path, check=false swallow path.
    A local CapturingFrameworkStatusReporter + SPI registration under
    src/test/resources provides the capture sink (MockFrameworkStatus-
    Reporter is scoped to dubbo-common tests and not reachable here).

Behavior change

Scenario Before After
Both arms succeed 1 coarse registration report 2 outcome reports, one per mode, status=SUCCESS
One arm fails, check=false on that registry URL exception bubbles out, sibling arm may be skipped failure is tagged + reported FAILED, returns false,
sibling arm continues
One arm fails, check=true exception bubbles out (no outcome report) outcome still reported FAILED then the original exception is rethrown
Reporter itself throws would leak into registration flow swallowed — reporting never affects registration

Checklist

  • Make sure there is a GitHub_issue field for the change.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Write necessary unit-test to verify your logic correction. If the new feature or significant change is committed, please remember to add sample in dubbo samples project.
  • Make sure gitHub actions can pass. Why the workflow is failing and how to fix it?

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 28, 2026

Codecov Report

❌ Patch coverage is 95.12195% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.81%. Comparing base (6916d1b) to head (1d82272).

Files with missing lines Patch % Lines
...e/dubbo/registry/integration/RegistryProtocol.java 93.10% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##                3.3   #16248      +/-   ##
============================================
+ Coverage     60.78%   60.81%   +0.03%     
- Complexity    11763    11779      +16     
============================================
  Files          1953     1953              
  Lines         89186    89224      +38     
  Branches      13454    13458       +4     
============================================
+ Hits          54209    54259      +50     
+ Misses        29400    29395       -5     
+ Partials       5577     5570       -7     
Flag Coverage Δ
integration-tests-java21 32.13% <63.41%> (-0.04%) ⬇️
integration-tests-java8 32.26% <63.41%> (+0.03%) ⬆️
samples-tests-java21 32.21% <60.97%> (+0.01%) ⬆️
samples-tests-java8 29.88% <60.97%> (+0.07%) ⬆️
unit-tests-java11 59.04% <95.12%> (+0.03%) ⬆️
unit-tests-java17 58.53% <95.12%> (+0.01%) ⬆️
unit-tests-java21 58.54% <95.12%> (+0.02%) ⬆️
unit-tests-java25 58.48% <95.12%> (+0.02%) ⬆️
unit-tests-java8 59.03% <95.12%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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] Dual registration: one registry's failure aborts the sibling arm under register-mode=all

2 participants