Uploaded image for project: 'Apache Curator'
  1. Apache Curator
  2. CURATOR-66

PathChildrenCache leaks a thread on close().

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Duplicate
    • 2.2.0-incubating
    • None
    • Recipes
    • None

    Description

      The PathChildrenCache does not shutdown its ExecutorService in close(). As a result, using any of the PathChildrenCache constructors that create a single threaded executor (which is all of them but the one that takes an ExecutorService explicitly) will leak a thread when PathChildrenCache.close() is called.

      Here's a program that reproduces the error. Currently it prints "# Total PathChildrenCache threads: 100" to indicate that 100 threads were leaked.

      import org.apache.curator.ensemble.fixed.FixedEnsembleProvider;
      import org.apache.curator.framework.CuratorFramework;
      import org.apache.curator.framework.CuratorFrameworkFactory;
      import org.apache.curator.framework.recipes.cache.PathChildrenCache;
      import org.apache.curator.retry.RetryOneTime;
      
      import java.util.Map;
      
      public class ThreadLeakTest {
          public static final int NUM_ITERATIONS = 100;
      
          public static void main(String[] args) throws Exception {
              CuratorFramework curator = CuratorFrameworkFactory.builder()
                      .ensembleProvider(new FixedEnsembleProvider("localhost:2181"))
                      .retryPolicy(new RetryOneTime(100))
                      .build();
              curator.start();
      
              for (int i = 0; i < NUM_ITERATIONS; i++) {
                  PathChildrenCache cache = new PathChildrenCache(curator, "/", true);
                  cache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE);
                  Thread.sleep(10);
                  cache.close();
              }
      
              curator.close();
      
              // Wait for things to settle
              Thread.sleep(1000);
      
              int threadCount = 0;
              Map<Thread,StackTraceElement[]> allThreads = Thread.getAllStackTraces();
              for (Thread thread : allThreads.keySet()) {
                  if (thread.getName().startsWith("PathChildrenCache")) {
                      System.out.printf("Thread still alive: %s%n", thread.getName());
                      threadCount++;
                  }
              }
              System.out.printf("# Total PathChildrenCache threads: %d%n", threadCount);
          }
      }
      

      Workaround: use the PathChildrenCache constructor that takes an ExecutorService and call shutdown() yourself. Note that closing the CuratorFramework ZK connection does not clean up the leaked threads.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              ssmith Shawn Smith
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: