Skip to content

fix(registry-nacos): guard lazy scheduler creation in NacosRegistry with double-checked locking - #16462

Open
Lubaoshuai wants to merge 1 commit into
apache:3.3from
Lubaoshuai:fix/nacos-registry-scheduler-dcl
Open

Lubaoshuai wants to merge 1 commit into
apache:3.3from
Lubaoshuai:fix/nacos-registry-scheduler-dcl

Conversation

@Lubaoshuai

Copy link
Copy Markdown

What is the purpose of the change

Concurrent admin-protocol subscriptions can leak non-daemon scheduler threads in NacosRegistry.

scheduleServiceNamesLookup performs an unsynchronized check-then-act on the scheduledExecutorService field: two concurrent subscribe calls with protocol=admin (e.g. multiple Dubbo Admin/ops clients) can both observe null and each create their own single-thread scheduled executor. shutdownServiceNamesLookup() only shuts down the last assigned reference, so every racing duplicate executor keeps polling getAllServiceNames() forever. The default thread factory also creates non-daemon threads, so the leaked schedulers block JVM exit.

Brief changelog

  • Create the scheduler under double-checked locking and publish the volatile field only after the periodic task has been scheduled on the local reference.
  • Use a named daemon thread factory (Dubbo-Nacos-Registry-Scheduler) so leaks, if any, are identifiable in thread dumps and cannot block shutdown.

Verifying this change

  • Added NacosRegistryTest.testConcurrentAdminSubscribeCreatesSingleDaemonScheduler: 8 concurrent admin-protocol subscribes against a mock NamingService assert exactly one scheduler thread exists, it is a daemon, and it terminates after unsubscribe.
  • mvn -pl dubbo-registry/dubbo-registry-nacos -am test -Dtest=NacosRegistryTest passes (6/6).

Fixes #15886

…ith double-checked locking

scheduleServiceNamesLookup performed an unsynchronized check-then-act on
the scheduledExecutorService field. Concurrent admin-protocol subscribes
could each create their own single-thread executor; only the last
assigned reference is shut down in shutdownServiceNamesLookup, leaking
non-daemon scheduler threads that keep polling Nacos forever and block
JVM exit. Create the executor under double-checked locking, publish it
after the task is scheduled, and use a named daemon thread factory.

Fixes apache#15886
@codecov-commenter

codecov-commenter commented Sep 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 33.33333% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.97%. Comparing base (dab47b7) to head (0600e1d).

Files with missing lines Patch % Lines
...org/apache/dubbo/registry/nacos/NacosRegistry.java 33.33% 12 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##                3.3   #16462      +/-   ##
============================================
+ Coverage     60.91%   60.97%   +0.05%     
- Complexity       15    11774   +11759     
============================================
  Files          1953     1953              
  Lines         89271    89275       +4     
  Branches      13473    13474       +1     
============================================
+ Hits          54383    54436      +53     
+ Misses        29309    29256      -53     
- Partials       5579     5583       +4     
Flag Coverage Δ
integration-tests-java21 32.14% <0.00%> (+<0.01%) ⬆️
integration-tests-java8 32.24% <0.00%> (+0.03%) ⬆️
samples-tests-java21 32.12% <0.00%> (-0.05%) ⬇️
samples-tests-java8 29.80% <0.00%> (-0.03%) ⬇️
unit-tests-java11 59.25% <33.33%> (+0.08%) ⬆️
unit-tests-java17 58.68% <33.33%> (+0.02%) ⬆️
unit-tests-java21 58.66% <33.33%> (+0.01%) ⬆️
unit-tests-java25 58.65% <27.77%> (+0.04%) ⬆️
unit-tests-java8 59.18% <33.33%> (+<0.01%) ⬆️

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

☔ View full report in Codecov by Harness.
📢 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] Thread leak in NacosRegistry.scheduleServiceNamesLookup due to race condition

2 participants