BufferPoolPruner does not shutdown when close client

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Minor - P4
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • None
    • Java Drivers
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      When creating MongoClient via MongoClients.create(settings) in PowerOfTwoBufferPool class a ScheduledExecutorService object is created by:

      pruner = Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory("BufferPoolPruner"));

      This thread is not closed when calling close() method on MongoClient. This causes a problem when we close the process but do not close the entire JVM in which the code was run. If we run code on container like Tomcat or Flink, the thread remains as well as the classes that depend on it which results in GC not being able to delete data and increasing metaspace.

      I tested it on versions 4.11.4, 5.1.3 and 5.2.0. Standalone and shared cluster.

       

      How to Reproduce

       

      import com.mongodb.ConnectionString;
      import com.mongodb.MongoClientSettings;
      import com.mongodb.MongoCredential;
      import com.mongodb.client.MongoClient;
      import com.mongodb.client.MongoClients;
      
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      import java.util.concurrent.Future;
      
      public class MongoClientBug {
      
          public static void main(String[] args) throws Exception {
              MongoCredential credential = MongoCredential
                      .createCredential(
                              "root",
                              "admin",
                              "root".toCharArray());
      
              MongoClientSettings settings = MongoClientSettings
                      .builder()
                      .credential(credential)
                      .applyConnectionString(new ConnectionString("mongodb://localhost:27017"))
                      .build();
      
              MongoClient mongoClient = MongoClients.create(settings);
      
              ExecutorService executorService = Executors.newSingleThreadExecutor();
              Future<?> submit = executorService.submit(() -> {
                  mongoClient.close();
                  System.out.println("close done");
              });
      
              Object o = submit.get();
      
              long l = System.currentTimeMillis();
              long timeperiod = 1000 * 60 * 5;
              while(System.currentTimeMillis() - l < timeperiod) {
                  System.out.println("Waiting");
                  Thread.sleep(1000);
              }
              System.out.println("Close JVM");
          }
      }
        

       

       

      Additional Background

            Assignee:
            Unassigned
            Reporter:
            Michał Szostek
            None
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: