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

Monitors do not handle a `moreToCome: false` when using the streaming protocol

    • Not Needed

      What problem are you facing?

      If the server ever responds with `moreToCome: false` when using the streaming protocol with exhaust support, monitors hang and are unable to continue monitoring the server.

      Tangentially related - the Node driver's SDAM also hangs when exhaust support is not enabled.  In practice, this is not an issue because we always enable exhaust support but this could change.  Additionally, this is a different manifestation of the same bug that impacts exhaust_support for the streaming protocol, and is an easier mechanism to reproduce the issue.

      The spec outlines the correct behavior here, which the Node driver does not implement.

      A client follows these rules when processing the hello or legacy hello exhaust response:

      • If the response is successful (includes "ok:1") and does not include the OP_MSG moreToCome flag, then the client initiates a new awaitable hello or legacy hello with the topologyVersion field from the previous response.

      What driver and relevant dependency versions are you using?

      All driver versions since the streaming protocol was introduced.

      Steps to reproduce?

      In monitor.ts, disable exhaust support by removing the `exhaustAllowed: true` from the hello's options.

      Run the following script against a replica set.  Once the new primary has been elected, write errors begin and never end.

      import { setTimeout } from 'timers/promises';
      import { inspect } from 'util';
      
      import { MongoClient, ReadPreference } from './src';
      
      async function repl_set_step_down(client: MongoClient) {
        await client
          .db('admin')
          .command({ replSetFreeze: 0 }, { readPreference: ReadPreference.secondary });
        await client.db('admin').command({
          replSetStepDown: 1,
          secondaryCatchUpPeriodSecs: 1
        });
      }
      
      function supress(fn) {
        return () => fn().catch(deep_log);
      }
      
      function deep_log(obj) {
        console.error(inspect(obj, { depth: Infinity }));
      }
      
      async function repeatedly_on_interval(fn, interval) {
        for (; ; await setTimeout(interval)) {
          await fn();
        }
      }
      
      async function run() {
        const client = new MongoClient(process.env.MONGODB_URI!);
      
        await client.connect();
        repeatedly_on_interval(
          supress(() => client.db('foo').collection('bar').insertOne({ name: 'bailey' })),
          5000
        );
        repeatedly_on_interval(
          supress(() => repl_set_step_down(client)),
          30000
        );
      }
      
      run();
      

            Assignee:
            Unassigned Unassigned
            Reporter:
            bailey.pearson@mongodb.com Bailey Pearson
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: