[BUG] — `HierarchicalWheelTimer`: non-daemon worker thread never stopped on `shutdown()` + unbounded single-thread task executor
- Dominant language
- Java
- Stars
- 8.8k
- Forks
- 3.1k
- Avg merge
- 7d 1h
- Merged PRs (30d)
- 85
Description
- severity: High (leak) / Medium (bottleneck)
- files: `shenyu-common/src/main/java/org/apache/shenyu/common/timer/HierarchicalWheelTimer.java:83-86` (`ShenyuThreadFactory.create(executorName, false)` → non-daemon), `:84-85` (`taskExecutor = new ThreadPoolExecutor(1,1,0L,MS,new LinkedBlockingQueue<>())`), `:146-148` (`shutdown` only stops `taskExecutor`, never `workerThread`), `:164-170` (`Worker.run` `while(true)` swallows `InterruptedException`)
- description: `shutdown()` never stops/interrupts the non-daemon `workerThread`, so its `while(true)` loop keeps running and ignores interrupts → thread leak + JVM hangs on redeploy. All expired timer tasks run on a single-thread executor with an *unbounded* `LinkedBlockingQueue` → burst of simultaneous expirations or any slow task creates head-of-line blocking and unbounded queue growth. Used by `FailbackRegistryRepository` (client) and `FallbackShenyuClientRegisterService` (admin).
- impact: Leaked non-daemon thread on redeploy; retry backpressure bottleneck.
- suggested_fix: Make `workerThread` a daemon (or interrupt+join in `shutdown`); bound `taskExecutor`'s queue with a real rejection handler.
- confidence: High
---
_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
Start with shenyu-common/src/main/java/org/apache/shenyu/common/timer/HierarchicalWheelTimer.java, especially the constructor lines 83-86, shutdown at 146-148, and Worker.run at 164-170. Trace its use from FailbackRegistryRepository and FallbackShenyuClientRegisterService, then define and verify shutdown behavior and bounded executor backpressure. Done means shutdown no longer leaves the worker running and expired-task bursts cannot grow an unbounded queue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100