QiuYucheng2003 opened a new issue, #25153:
URL: https://github.com/apache/pulsar/issues/25153

   ### Search before reporting
   
   - [x] I searched in the [issues](https://github.com/apache/pulsar/issues) 
and found nothing similar.
   
   
   ### Read release policy
   
   - [x] I understand that [unsupported 
versions](https://pulsar.apache.org/contribute/release-policy/#supported-versions)
 don't get bug fixes. I will attempt to reproduce the issue on a supported 
version of Pulsar client and Pulsar broker.
   
   
   ### User environment
   
   Broker/Client version: All versions
   OS/Java: All
   
   ### Issue Description
   
   What happened? 
   The LoadSimulationController class initializes a private static final 
ExecutorService threadPool (Line 77) using Executors.newCachedThreadPool(). 
There is no mechanism to shut down this thread pool.
   
   What did I expect to happen? 
   Resources, especially thread pools, should be managed and released properly 
when the controller instance is no longer needed or when the application shuts 
down.
   
   What actually happened instead? 
   The static thread pool persists for the lifetime of the JVM. Since 
newCachedThreadPool creates non-daemon threads by default, these active threads 
prevent the JVM from shutting down cleanly in embedded scenarios and cause 
thread leakage if the class is loaded/unloaded in a containerized test 
environment.
   
   Why do I believe this is a bug?
   While LoadSimulationController is often used as a CLI tool (where 
System.exit cleans up resources), it resides in the pulsar-testclient module. 
If this class is used as a library within a larger automation framework, the 
unclosed static thread pool leads to Thread Leaks and Platform Resource 
Exhaustion.
   
   ### Error messages
   
   ```text
   N/A (This is a static code analysis finding relating to a resource leak)
   ```
   
   ### Reproducing the issue
   
   1. Inspect the source code of 
org/apache/pulsar/testclient/LoadSimulationController.java.
   
   2. Locate Line 77: private static final ExecutorService threadPool = 
Executors.newCachedThreadPool();.
   
   3 Search for usages of threadPool.
   
   4. Observe that threadPool.shutdown() or threadPool.shutdownNow() is never 
called in the entire class.
   
   ### Additional information
   
   Suggested Fix: 
   Change threadPool from a static field to an instance field and implement a 
cleanup method (e.g., close() or shutdown()) to explicitly terminate the 
ExecutorService.
   
   // Current Code (Leak Risk)
   private static final ExecutorService threadPool = 
Executors.newCachedThreadPool();
   
   // Suggested Code
   private final ExecutorService threadPool = Executors.newCachedThreadPool();
   
   public void shutdown() {
       threadPool.shutdown();
   }
   
   ### Are you willing to submit a PR?
   
   - [x] I'm willing to submit a PR!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to