-
Type: Bug
-
Resolution: Gone away
-
Priority: Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
Labels:
The server selection spec section "Topology type: Single" says:
- Type Standalone: clients MUST NOT send the read preference to the server
- For all other types, using OP_QUERY: clients MUST always set the slaveOK wire
protocol flag on reads to ensure that any server type can handle the request.
As observed in tests of CDRIVER-3498, libmongoc sets slaveOk for a standalone in topology type single, which seems to differ slightly from the spec. This may not be harmful (as we have not observed any bad behavior due to this) but is still a deviation.
Here is a repro test:
static bool _auto_ok (request_t *request, void* unused) { if (0 == strcmp (request->command_name, "isMaster")) { return false; } mock_server_replies_simple (request, "{'ok': 1}"); return true; } static void test_read_prefs_bugs (void) { mock_server_t *server; mongoc_client_t *client; mongoc_read_prefs_t *read_prefs_primary; mongoc_uri_t *uri; bson_error_t error; bool ret; mongoc_server_description_t *sd; read_prefs_primary = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); MONGOC_DEBUG ("Testing standalone"); /* Use OP_QUERY */ server = mock_server_with_autoismaster (WIRE_VERSION_OP_MSG - 1); mock_server_run (server); mock_server_autoresponds (server, _auto_ok, NULL, NULL); uri = mongoc_uri_copy (mock_server_get_uri (server)); mongoc_uri_set_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, true); client = mongoc_client_new_from_uri (uri); /* Test a command with primary read preference. */ MONGOC_DEBUG ("primary read prefs"); ret = mongoc_client_command_simple (client, "admin", tmp_bson("{'ping': 1}"), read_prefs_primary, NULL, NULL); ASSERT_OR_PRINT (ret, error); sd = mongoc_client_select_server (client, false, NULL, &error); ASSERT (client->topology->description.type == MONGOC_TOPOLOGY_SINGLE); ASSERT (sd->type == MONGOC_SERVER_STANDALONE); mongoc_read_prefs_destroy (read_prefs_primary); mongoc_server_description_destroy (sd); mock_server_destroy (server); mongoc_client_destroy (client); }
Using the test environment variable MONGOC_TEST_SERVER_LOG=stdout, this shows the SLAVE_OK flag sent:
> MONGOC_TEST_SERVER_LOG=stdout ./cmake-build/src/libmongoc/test-libmongoc --no-fork -l /ReadPrefs/bugs -d Begin /ReadPrefs/bugs, seed 3107453679 2020/05/11 13:35:35.0641: [23125]: DEBUG: mongoc: Testing standalone listening on port 50677 2020/05/11 13:35:35.0644: [23125]: DEBUG: mongoc: primary read prefs 0.01 50678 -> server port 50677 (connected) 0.02 50678 -> 50677 OP_QUERY admin.$cmd { "isMaster" : 1, "client" : { "driver" : { "name" : "mongoc", "version" : "1.17.0-pre" }, "os" : { "type" : "Darwin", "name" : "macOS", "version" : "18.7.0", "architecture" : "x86_64" }, "platform" : "cfg=0x0280cea0e9 posix=200112 stdc=201112 CC=clang 9.0.0 (git://github.com/llvm/llvm-project.git 0399d5a9682b3cef71c653373e38890c63c4c365)" }, "compression" : [ ] } flags=SLAVE_OK n_return=-1 0.02 50678 <- 50677 OP_REPLY { "ok" : 1.0, "ismaster" : true, "minWireVersion" : 0, "maxWireVersion" : 5 } 0.02 50678 -> 50677 OP_QUERY admin.$cmd { "ping" : 1 } flags=SLAVE_OK n_return=-1 0.02 50678 <- 50677 OP_REPLY { "ok" : 1 }