Uploaded image for project: 'Node.js Driver'
  1. Node.js Driver
  2. NODE-1828

close() does not release all resources until socket timeout

    • Type: Icon: Task Task
    • Resolution: Fixed
    • Priority: Icon: Minor - P4 Minor - P4
    • 3.2.0
    • Affects Version/s: 3.1.10, 3.1.11
    • Component/s: Native
    • Labels:
    • Environment:
      Linux/Docker, MacOS

      It appears to me that the Node.js driver waits for connectTimeoutMS milliseconds until it releases all resources after MongoClient.close() is called, which resolves the Promise immediately. I would expect that when all connections are closed, also all other resources (socket connections, timeouts...?) are released.

      This is a problem when testing with Jest, especially in a CI environment such as Bitbucket Pipelines.

      To be clear, I can confirm that the actual MongoDB connection(s) are indeed closed as soon as I call the close method and the Promise returned by close resolves pretty much immediately. It's Jest that keeps waiting, because it notices that not all resources are freed.

      I figured out that Jest not exiting after a test involving MongoDB is related to the time specified in connection option connectTimeoutMS, which is by default 6 minutes. If I set it to a lower value such as 5000ms or 500ms, that will be the time the exit is delayed for. Although I don't know what is going on under the hood, I get the feeling that something is not quite right there and relying on a connection timeout points to a deeper problem.

      Example test file:

      const { MongoClient } = require('mongodb');
      let client;
      let db;
      beforeAll(async () => {
          client = await MongoClient.connect('mongodb://localhost:27017', {
              useNewUrlParser: true,
              socketTimeoutMS: 5000, // <-- this is how long the exit is delayed
          });
          db = await client.db('testdb');
      });
      afterAll(async () => {
          await client.close();
      });
      it('should insert and find document', async () => {
          const collection = db.collection('files');
          await collection.insert({name: 'Jest'});
          const doc = await collection.findOne({name: 'Jest'});
          expect(doc._id).toBeDefined();
          expect(doc.name).toBe('Jest');
      });

       

      I am not sure if I'm doing something wrong or if this is a bug. I have also posted a question to StackOverflow. Thanks!

            Assignee:
            matt.broadstone@mongodb.com Matt Broadstone
            Reporter:
            nick@cloudunder.io Nick Zahn
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: