Uploaded image for project: 'C Driver'
  1. C Driver
  2. CDRIVER-3117

mongoc_database_command_with_opts does not default to DB read preference as documented

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 1.15.0
    • Affects Version/s: 1.13.0, 1.14.0
    • Component/s: None

      According to the documentation, if no read preference is passed in as a parameter and the command is not run in a transaction, mongoc_database_command_with_opts will use the database's read preference.

      However, this does not seem to be the case. 

      I've managed to repro this in both 1.13.0 and 1.14.0 from Swift as follows, running against MongoDB 4.0.5 (omitted some cleanup code for brevity): 

      // create client
      let uri = mongoc_uri_new_with_error("mongodb://localhost:27017", nil)
      let client = mongoc_client_new_from_uri(uri)
      
      // set up command monitoring
      let callbacks = mongoc_apm_callbacks_new()
      mongoc_apm_set_command_started_cb(callbacks, commandStarted) // this is a callback that just prints the command document out.
      mongoc_client_set_apm_callbacks (client, callbacks, nil)
      
      // create DB and set read preference
      let db = mongoc_client_get_database(client, "foo")
      let rp = mongoc_read_prefs_new(MONGOC_READ_SECONDARY)
      mongoc_database_set_read_prefs(db, rp)
      
      // verify read preference is secondary
      let actualRP = mongoc_database_get_read_prefs(db)
      let actualMode = mongoc_read_prefs_get_mode(actualRP)
      print(actualMode) // prints mongoc_read_mode_t(rawValue: 2) (i.e. secondary)
      
      // construct a command
      let command = bson_new()
      if !bson_append_utf8(command, "find", -1, "coll1", -1) {
          print("failed to append")
          return
      }
      
      let reply = bson_new()
      let result = mongoc_database_command_with_opts(db,
                                                     command, 
                                                     nil, /* read pref */
                                                     nil, /* opts */
                                                     reply,
                                                     nil /* error */)
      

      The APM callback prints out the following command, which shows primaryPreferred used as the read preference:

      { "find" : "coll1", "$db" : "foo", "$readPreference" : { "mode" : "primaryPreferred" }, "lsid" : { "id" : { "$binary" : { "base64": "5p0G9OxnTWqsjdLf+3Lr1g==", "subType" : "04" } } } }
      

      If I explicitly pass in the secondary read preference to mongoc_database_command_with_opts, the command uses secondary as well. 

      Is this behavior intended?

      We use this method for our MongoDatabase.runCommand implementation. Currently we can work around this by just always passing in the DB's read preference if the user doesn't specify one via RunCommandOptions

            Assignee:
            clyde.bazile@mongodb.com Clyde Bazile III (Inactive)
            Reporter:
            kaitlin.mahar@mongodb.com Kaitlin Mahar
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: