You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] — HierarchicalWheelTimer: non-daemon worker thread never stopped on shutdown() + unbounded single-thread task executor #6668
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.runwhile(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 unboundedLinkedBlockingQueue → 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.
Cross-link: related to the periodic-task / worker-thread lifecycle hardening pass #6608 (tracked there as a related, non-duplicate defect — this is an idempotent-start / worker-shutdown leak, not the exception-cancellation family). Folding into the same hardening pass if its scope is widened.
I checked the current upstream/master (09c6a528) against this report. The worker-thread shutdown part is already addressed by merged #6982 (58dd5a517): shutdown() interrupts the worker under the write lock, Worker.run() exits when interrupted, and HierarchicalWheelTimerTest#testShutdownStopsWorkerAndRejectsNewTasks joins the worker and asserts it has terminated.
The unbounded LinkedBlockingQueue remains. That is a separate overload/backpressure question: a bounded queue needs an explicit overflow policy because rejecting an expired timer callback can leave caller state stale, while caller-runs can stall the timing-wheel worker. Could we narrow this issue to the queue/backpressure behavior and agree on the expected overload semantics, while marking the worker-leak portion resolved by #6982?
Activity
github-actions commentedon Aug 3, 2026
👋 Hello @yuluo-yx
A new issue has been opened by @Aias00:
HierarchicalWheelTimer: non-daemon worker thread never stopped onshutdown()+ unbounded single-thread task executorHierarchicalWheelTimer: non-daemon worker thread never stopped onshutdown()+ unbounded single-thread task executor #6668Please review when you have time. Thank you! 🙏
Aias00 commentedon Aug 3, 2026
Cross-link: related to the periodic-task / worker-thread lifecycle hardening pass #6608 (tracked there as a related, non-duplicate defect — this is an idempotent-start / worker-shutdown leak, not the exception-cancellation family). Folding into the same hardening pass if its scope is widened.
sunnysabor commentedon Oct 1, 2026
I checked the current
upstream/master(09c6a528) against this report. The worker-thread shutdown part is already addressed by merged #6982 (58dd5a517):shutdown()interrupts the worker under the write lock,Worker.run()exits when interrupted, andHierarchicalWheelTimerTest#testShutdownStopsWorkerAndRejectsNewTasksjoins the worker and asserts it has terminated.The unbounded
LinkedBlockingQueueremains. That is a separate overload/backpressure question: a bounded queue needs an explicit overflow policy because rejecting an expired timer callback can leave caller state stale, while caller-runs can stall the timing-wheel worker. Could we narrow this issue to the queue/backpressure behavior and agree on the expected overload semantics, while marking the worker-leak portion resolved by #6982?wy471x commentedon Oct 4, 2026
/assign
fix: make HierarchicalWheelTimer threads daemon and bound its task qu…