[BUG] SingletonExecutor worker threads never shut down (incomplete #6262 fix)
- Dominant language
- Java
- Stars
- 8.8k
- Forks
- 3.1k
- Avg merge
- 7d 1h
- Merged PRs (30d)
- 85
Description
- Severity: High
- Location:
`shenyu-disruptor/src/main/java/org/apache/shenyu/disruptor/thread/OrderlyExecutor.java:37,66-77`; `shenyu-disruptor/src/main/java/org/apache/shenyu/disruptor/provider/DisruptorProvider.java:114-121`
-
Description:
In orderly mode `OrderlyExecutor` populates `virtualExecutors` (a `ConcurrentSkipListMap`) with `corePoolSize` `SingletonExecutor` instances, each its own `ThreadPoolExecutor(1,1,…,new LinkedBlockingQueue<>(), threadFactory)`. `DisruptorProvider.shutdown()` only calls `executor.shutdown()` on the outer `OrderlyExecutor`; `OrderlyExecutor` does not override `shutdown()`/`shutdownNow()` to cascade. The worker thread factory is `DisruptorThreadFactory.create("shenyu_disruptor_consumer_", false)` — `daemon=false` (`DisruptorProviderManage.java:110`) — so the leaked workers are non-daemon and keep the JVM alive.
-
Impact:
After `DisruptorProvider.shutdown()` in orderly mode, `corePoolSize` non-daemon threads (default `availableProcessors()*2`) stay alive forever; JVM cannot exit cleanly. Hot-reload/repeated-init leaks threads each cycle.
-
Suggested fix:
Override `shutdown()`/`shutdownNow()` in `OrderlyExecutor` to iterate `virtualExecutors.values()` and shut down each `SingletonExecutor`, then `super.shutdown()`.
-
Confidence: High
- Related existing: #6262 — but the merged fix only added outer `executor.shutdown()`; inner `SingletonExecutor` leak unfixed. Distinct facet.
---
_Identified during the 2026-08-02 deep re-scan; full list in [`docs/scan2-2026-08-02/00-consolidated-critical-high.md`](docs/scan2-2026-08-02/00-consolidated-critical-high.md)._
Contributor guide
No contributing guide indexed for this repository
Research direction
Read OrderlyExecutor.java at the listed fields and executor methods, then inspect DisruptorProvider.shutdown() and DisruptorProviderManage.java:110 to confirm the non-daemon thread factory. Trace how orderly mode populates virtualExecutors and how shutdown currently reaches the outer executor. Done means shutdown and shutdownNow cascade to the SingletonExecutor workers so repeated initialization does not leave non-daemon threads keeping the JVM alive.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 70/100