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

Investigate: Are parallel invocations of MongoClient.close safe?

    • Type: Icon: Question Question
    • Resolution: Unresolved
    • Priority: Icon: Minor - P4 Minor - P4
    • None
    • Affects Version/s: None
    • Component/s: Connection Layer

      Question

      Is it possible that invoking close more than once in parallel could lead to an error? (somewhat like a double free). Should this be something the driver handles similar to NODE-5106 with connect?

      I'm wondering if `.close` also has a parallelism issue. Supposedly we could be calling `.end` on sockets more than once because as the first "`client.close`" promise is pending the I/O for socket closure the next promise could also synchronously reach the `.end` invocation.

      This may in fact not be the case but if it is we'll want to also fix that.

      I contrived an example, I have to use sleep 1ms to make the promises offset by a bit but I would imagine in real world scenario a delay like that could occur depending on what else is in the event loop.

      Example script that calls .end in parallel

      import { once } from 'events';
      import { Socket } from 'net';
      import { setTimeout as sleep } from 'timers/promises';
      import { promisify } from 'util';
      
      const socket = new Socket();
      const willConnect = once(socket, 'connect');
      socket.connect({ host: '127.0.0.1', port: 2390 }).setDefaultEncoding('utf8').setEncoding('utf8');
      await willConnect;
      
      await promisify(callback => socket.write('hello\n', callback))();
      
      // MongoClient .close in parallel
      await Promise.all([
        promisify(callback => socket.end(callback))(),
        sleep(1).then(() => promisify(callback => socket.end(callback))())
      ]);
      
      Error [ERR_STREAM_ALREADY_FINISHED]: Cannot call end after a stream was finished
          at new NodeError (node:internal/errors:393:5)
          at Writable.end (node:internal/streams/writable:637:11)
          at Socket.end (node:net:691:31)
        code: 'ERR_STREAM_ALREADY_FINISHED'
      }
      

            Assignee:
            Unassigned Unassigned
            Reporter:
            neal.beeken@mongodb.com Neal Beeken
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: