diff options
author | Pavi Vetriselvan <pavithra.vetriselvan@mongodb.com> | 2020-07-30 12:39:35 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-08-20 11:55:10 +0000 |
commit | 694f98a8c171701ebb3af3f2b865e9f963a9983c (patch) | |
tree | 0bb9715c78c59442db3e05cd4002839a512ef2fa | |
parent | f63a0a4204266c661e87ce704d91ade9511f1fd5 (diff) | |
download | mongo-694f98a8c171701ebb3af3f2b865e9f963a9983c.tar.gz |
SERVER-49986 Convert isMaster command to hello and keep isMaster, ismaster aliases
(cherry picked from commit 9a4be902441496be7ef40e5404a91ac30dc81f77)
-rw-r--r-- | etc/backports_required_for_multiversion_tests.yml | 16 | ||||
-rw-r--r-- | jstests/core/ismaster.js | 96 | ||||
-rw-r--r-- | jstests/core/list_commands.js | 14 | ||||
-rw-r--r-- | jstests/core/views/views_all_commands.js | 2 | ||||
-rw-r--r-- | jstests/replsets/db_reads_while_recovering_all_commands.js | 2 | ||||
-rw-r--r-- | jstests/sharding/database_versioning_all_commands.js | 2 | ||||
-rw-r--r-- | jstests/sharding/ismaster.js | 94 | ||||
-rw-r--r-- | jstests/sharding/read_write_concern_defaults_application.js | 2 | ||||
-rw-r--r-- | jstests/sharding/safe_secondary_reads_drop_recreate.js | 2 | ||||
-rw-r--r-- | jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js | 2 | ||||
-rw-r--r-- | jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_info.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/service_entry_point_common.cpp | 5 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_is_master_cmd.cpp | 15 | ||||
-rw-r--r-- | src/mongo/s/commands/strategy.cpp | 23 |
15 files changed, 181 insertions, 111 deletions
diff --git a/etc/backports_required_for_multiversion_tests.yml b/etc/backports_required_for_multiversion_tests.yml index 849eb3d27f9..78eb527faeb 100644 --- a/etc/backports_required_for_multiversion_tests.yml +++ b/etc/backports_required_for_multiversion_tests.yml @@ -73,6 +73,22 @@ all: test_file: jstests/sharding/retryable_writes.js - ticket: SERVER-31368 test_file: jstests/sharding/log_remote_op_wait.js + - ticket: SERVER-49986 + test_file: jstests/core/ismaster.js + - ticket: SERVER-49986 + test_file: jstests/core/views/views_all_commands.js + - ticket: SERVER-49986 + test_file: jstests/sharding/database_versioning_all_commands.js + - ticket: SERVER-49986 + test_file: jstests/sharding/ismaster.js + - ticket: SERVER-49986 + test_file: jstests/sharding/read_write_concern_defaults_application.js + - ticket: SERVER-49986 + test_file: jstests/sharding/safe_secondary_reads_drop_recreate.js + - ticket: SERVER-49986 + test_file: jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js + - ticket: SERVER-49986 + test_file: jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js suites: diff --git a/jstests/core/ismaster.js b/jstests/core/ismaster.js index a29be88331c..a8ed96a4ac1 100644 --- a/jstests/core/ismaster.js +++ b/jstests/core/ismaster.js @@ -1,45 +1,61 @@ +/** + * This test ensures that the hello command and its aliases, ismaster and isMaster, are all + * accepted. + */ "use strict"; -var res = db.isMaster(); -// check that the fields that should be there are there and have proper values -assert(res.maxBsonObjectSize && isNumber(res.maxBsonObjectSize) && res.maxBsonObjectSize > 0, - "maxBsonObjectSize possibly missing:" + tojson(res)); -assert(res.maxMessageSizeBytes && isNumber(res.maxMessageSizeBytes) && res.maxBsonObjectSize > 0, - "maxMessageSizeBytes possibly missing:" + tojson(res)); -assert(res.maxWriteBatchSize && isNumber(res.maxWriteBatchSize) && res.maxWriteBatchSize > 0, - "maxWriteBatchSize possibly missing:" + tojson(res)); -assert.eq("boolean", typeof res.ismaster, "ismaster field is not a boolean" + tojson(res)); -assert(res.ismaster === true, "ismaster field is false" + tojson(res)); -assert(res.localTime, "localTime possibly missing:" + tojson(res)); -assert(res.connectionId, "connectionId missing or false" + tojson(res)); -if (!testingReplication) { - var badFields = []; - var unwantedReplSetFields = [ - "setName", - "setVersion", - "secondary", - "hosts", - "passives", - "arbiters", - "primary", - "aribterOnly", - "passive", - "slaveDelay", - "hidden", - "tags", - "buildIndexes", - "me" - ]; - var field; - // check that the fields that shouldn't be there are not there - for (field in res) { - if (!res.hasOwnProperty(field)) { - continue; - } - if (Array.contains(unwantedReplSetFields, field)) { - badFields.push(field); +function checkResponseFields(commandString) { + var res = db.runCommand(commandString); + // check that the fields that should be there are there and have proper values + assert(res.maxBsonObjectSize && isNumber(res.maxBsonObjectSize) && res.maxBsonObjectSize > 0, + "maxBsonObjectSize possibly missing:" + tojson(res)); + assert( + res.maxMessageSizeBytes && isNumber(res.maxMessageSizeBytes) && res.maxBsonObjectSize > 0, + "maxMessageSizeBytes possibly missing:" + tojson(res)); + assert(res.maxWriteBatchSize && isNumber(res.maxWriteBatchSize) && res.maxWriteBatchSize > 0, + "maxWriteBatchSize possibly missing:" + tojson(res)); + assert.eq("boolean", typeof res.ismaster, "ismaster field is not a boolean" + tojson(res)); + + // TODO SERVER-49988: Check for res.isWritablePrimary instead of res.ismaster if a hello command + // was executed. + assert(res.ismaster === true, "ismaster field is false" + tojson(res)); + assert(res.localTime, "localTime possibly missing:" + tojson(res)); + assert(res.connectionId, "connectionId missing or false" + tojson(res)); + + if (!testingReplication) { + var badFields = []; + var unwantedReplSetFields = [ + "setName", + "setVersion", + "secondary", + "hosts", + "passives", + "arbiters", + "primary", + "aribterOnly", + "passive", + "slaveDelay", + "hidden", + "tags", + "buildIndexes", + "me" + ]; + var field; + // check that the fields that shouldn't be there are not there + for (field in res) { + if (!res.hasOwnProperty(field)) { + continue; + } + if (Array.contains(unwantedReplSetFields, field)) { + badFields.push(field); + } } + assert( + badFields.length === 0, + "\nthe result:\n" + tojson(res) + "\ncontained fields it shouldn't have: " + badFields); } - assert(badFields.length === 0, - "\nthe result:\n" + tojson(res) + "\ncontained fields it shouldn't have: " + badFields); } + +checkResponseFields("hello"); +checkResponseFields("ismaster"); +checkResponseFields("isMaster"); diff --git a/jstests/core/list_commands.js b/jstests/core/list_commands.js index 6e63c179dfb..05c83db2b1f 100644 --- a/jstests/core/list_commands.js +++ b/jstests/core/list_commands.js @@ -22,19 +22,19 @@ assert(isSorted(commands)); // Test that result contains basic commands. assert(commands.hasOwnProperty("commands")); -assert(commands["commands"].hasOwnProperty("isMaster")); +assert(commands["commands"].hasOwnProperty("hello")); assert(commands["commands"].hasOwnProperty("insert")); assert(commands["commands"].hasOwnProperty("ping")); // Test that commands listed have required properties -const isMaster = commands["commands"]["isMaster"]; -assert(isMaster.hasOwnProperty("help")); -assert(isMaster.hasOwnProperty("slaveOk")); -assert(isMaster.hasOwnProperty("adminOnly")); -assert(isMaster.hasOwnProperty("requiresAuth")); +const hello = commands["commands"]["hello"]; +assert(hello.hasOwnProperty("help")); +assert(hello.hasOwnProperty("slaveOk")); +assert(hello.hasOwnProperty("adminOnly")); +assert(hello.hasOwnProperty("requiresAuth")); // Test that requiresAuth outputs correct value const insert = commands["commands"]["insert"]; -assert(isMaster["requiresAuth"] === false); +assert(hello["requiresAuth"] === false); assert(insert["requiresAuth"] === true); })(); diff --git a/jstests/core/views/views_all_commands.js b/jstests/core/views/views_all_commands.js index e559096c280..a329ab9e1a1 100644 --- a/jstests/core/views/views_all_commands.js +++ b/jstests/core/views/views_all_commands.js @@ -346,13 +346,13 @@ let viewsCommandTests = { grantRolesToRole: {skip: isUnrelated}, grantRolesToUser: {skip: isUnrelated}, handshake: {skip: isUnrelated}, + hello: {skip: isUnrelated}, hostInfo: {skip: isUnrelated}, httpClientRequest: {skip: isAnInternalCommand}, insert: {command: {insert: "view", documents: [{x: 1}]}, expectFailure: true}, internalRenameIfOptionsAndIndexesMatch: {skip: isAnInternalCommand}, invalidateUserCache: {skip: isUnrelated}, isdbgrid: {skip: isUnrelated}, - isMaster: {skip: isUnrelated}, killCursors: { setup: function(conn) { assert.commandWorked(conn.collection.remove({})); diff --git a/jstests/replsets/db_reads_while_recovering_all_commands.js b/jstests/replsets/db_reads_while_recovering_all_commands.js index b85311a68b5..5486af549a2 100644 --- a/jstests/replsets/db_reads_while_recovering_all_commands.js +++ b/jstests/replsets/db_reads_while_recovering_all_commands.js @@ -184,12 +184,12 @@ const allCommands = { grantPrivilegesToRole: {skip: isPrimaryOnly}, grantRolesToRole: {skip: isPrimaryOnly}, grantRolesToUser: {skip: isPrimaryOnly}, + hello: {skip: isNotAUserDataRead}, hostInfo: {skip: isNotAUserDataRead}, httpClientRequest: {skip: isNotAUserDataRead}, insert: {skip: isPrimaryOnly}, internalRenameIfOptionsAndIndexesMatch: {skip: isAnInternalCommand}, invalidateUserCache: {skip: isNotAUserDataRead}, - isMaster: {skip: isNotAUserDataRead}, killAllSessions: {skip: isNotAUserDataRead}, killAllSessionsByPattern: {skip: isNotAUserDataRead}, killCursors: {skip: isNotAUserDataRead}, diff --git a/jstests/sharding/database_versioning_all_commands.js b/jstests/sharding/database_versioning_all_commands.js index 3f385c8c5b3..8ca8f77976c 100644 --- a/jstests/sharding/database_versioning_all_commands.js +++ b/jstests/sharding/database_versioning_all_commands.js @@ -452,6 +452,7 @@ let testCases = { grantPrivilegesToRole: {skip: "always targets the config server"}, grantRolesToRole: {skip: "always targets the config server"}, grantRolesToUser: {skip: "always targets the config server"}, + hello: {skip: "executes locally on mongos (not sent to any remote node)"}, hostInfo: {skip: "executes locally on mongos (not sent to any remote node)"}, insert: { run: { @@ -463,7 +464,6 @@ let testCases = { }, invalidateUserCache: {skip: "executes locally on mongos (not sent to any remote node)"}, isdbgrid: {skip: "executes locally on mongos (not sent to any remote node)"}, - isMaster: {skip: "executes locally on mongos (not sent to any remote node)"}, killCursors: {skip: "requires a previously established cursor"}, killAllSessions: {skip: "always broadcast to all hosts in the cluster"}, killAllSessionsByPattern: {skip: "always broadcast to all hosts in the cluster"}, diff --git a/jstests/sharding/ismaster.js b/jstests/sharding/ismaster.js index 2d5cea7b586..a582f677241 100644 --- a/jstests/sharding/ismaster.js +++ b/jstests/sharding/ismaster.js @@ -1,42 +1,62 @@ +/** + * This test ensures that the hello command and its aliases, ismaster and isMaster, are all + * accepted by mongos. + */ "use strict"; var st = new ShardingTest({shards: 1, mongos: 1}); -var res = st.s0.getDB("admin").runCommand("ismaster"); -// check that the fields that should be there are there and have proper values -assert(res.maxBsonObjectSize && isNumber(res.maxBsonObjectSize) && res.maxBsonObjectSize > 0, - "maxBsonObjectSize possibly missing:" + tojson(res)); -assert(res.maxMessageSizeBytes && isNumber(res.maxMessageSizeBytes) && res.maxBsonObjectSize > 0, - "maxMessageSizeBytes possibly missing:" + tojson(res)); -assert.eq("boolean", typeof res.ismaster, "ismaster field is not a boolean" + tojson(res)); -assert(res.ismaster === true, "ismaster field is false" + tojson(res)); -assert(res.localTime, "localTime possibly missing:" + tojson(res)); -assert(res.msg && res.msg == "isdbgrid", "msg possibly missing or wrong:" + tojson(res)); -var unwantedFields = [ - "setName", - "setVersion", - "secondary", - "hosts", - "passives", - "arbiters", - "primary", - "aribterOnly", - "passive", - "slaveDelay", - "hidden", - "tags", - "buildIndexes", - "me" -]; -// check that the fields that shouldn't be there are not there -var badFields = []; -var field; -for (field in res) { - if (!res.hasOwnProperty(field)) { - continue; - } - if (Array.contains(unwantedFields, field)) { - badFields.push(field); + +function checkResponseFields(commandString) { + jsTestLog("Running the " + commandString + " command"); + var res = st.s0.getDB("admin").runCommand(commandString); + + // check that the fields that should be there are there and have proper values + assert(res.maxBsonObjectSize && isNumber(res.maxBsonObjectSize) && res.maxBsonObjectSize > 0, + "maxBsonObjectSize possibly missing:" + tojson(res)); + assert( + res.maxMessageSizeBytes && isNumber(res.maxMessageSizeBytes) && res.maxBsonObjectSize > 0, + "maxMessageSizeBytes possibly missing:" + tojson(res)); + + // TODO SERVER-49988: Check for res.isWritablePrimary instead of res.ismaster if a hello command + // was executed. + assert.eq("boolean", typeof res.ismaster, "ismaster field is not a boolean" + tojson(res)); + assert(res.ismaster === true, "ismaster field is false" + tojson(res)); + + assert(res.localTime, "localTime possibly missing:" + tojson(res)); + assert(res.msg && res.msg == "isdbgrid", "msg possibly missing or wrong:" + tojson(res)); + + var unwantedFields = [ + "setName", + "setVersion", + "secondary", + "hosts", + "passives", + "arbiters", + "primary", + "aribterOnly", + "passive", + "slaveDelay", + "hidden", + "tags", + "buildIndexes", + "me" + ]; + // check that the fields that shouldn't be there are not there + var badFields = []; + var field; + for (field in res) { + if (!res.hasOwnProperty(field)) { + continue; + } + if (Array.contains(unwantedFields, field)) { + badFields.push(field); + } } + assert(badFields.length === 0, + "\nthe result:\n" + tojson(res) + "\ncontained fields it shouldn't have: " + badFields); } -assert(badFields.length === 0, - "\nthe result:\n" + tojson(res) + "\ncontained fields it shouldn't have: " + badFields); + +checkResponseFields("hello"); +checkResponseFields("ismaster"); +checkResponseFields("isMaster"); + st.stop(); diff --git a/jstests/sharding/read_write_concern_defaults_application.js b/jstests/sharding/read_write_concern_defaults_application.js index d53cce7a65d..3f4b725572a 100644 --- a/jstests/sharding/read_write_concern_defaults_application.js +++ b/jstests/sharding/read_write_concern_defaults_application.js @@ -451,6 +451,7 @@ let testCases = { useLogs: true, }, handshake: {skip: "does not accept read or write concern"}, + hello: {skip: "does not accept read or write concern"}, hostInfo: {skip: "does not accept read or write concern"}, httpClientRequest: {skip: "does not accept read or write concern"}, insert: { @@ -463,7 +464,6 @@ let testCases = { }, internalRenameIfOptionsAndIndexesMatch: {skip: "internal command"}, invalidateUserCache: {skip: "does not accept read or write concern"}, - isMaster: {skip: "does not accept read or write concern"}, isdbgrid: {skip: "does not accept read or write concern"}, killAllSessions: {skip: "does not accept read or write concern"}, killAllSessionsByPattern: {skip: "does not accept read or write concern"}, diff --git a/jstests/sharding/safe_secondary_reads_drop_recreate.js b/jstests/sharding/safe_secondary_reads_drop_recreate.js index 7375971afd1..fc7e0906937 100644 --- a/jstests/sharding/safe_secondary_reads_drop_recreate.js +++ b/jstests/sharding/safe_secondary_reads_drop_recreate.js @@ -198,11 +198,11 @@ let testCases = { grantRolesToRole: {skip: "primary only"}, grantRolesToUser: {skip: "primary only"}, handshake: {skip: "does not return user data"}, + hello: {skip: "does not return user data"}, hostInfo: {skip: "does not return user data"}, insert: {skip: "primary only"}, invalidateUserCache: {skip: "does not return user data"}, isdbgrid: {skip: "does not return user data"}, - isMaster: {skip: "does not return user data"}, killAllSessions: {skip: "does not return user data"}, killAllSessionsByPattern: {skip: "does not return user data"}, killCursors: {skip: "does not return user data"}, diff --git a/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js b/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js index 53de9bc7be6..7d192f7b377 100644 --- a/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js +++ b/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js @@ -232,11 +232,11 @@ let testCases = { grantRolesToRole: {skip: "primary only"}, grantRolesToUser: {skip: "primary only"}, handshake: {skip: "does not return user data"}, + hello: {skip: "does not return user data"}, hostInfo: {skip: "does not return user data"}, insert: {skip: "primary only"}, invalidateUserCache: {skip: "does not return user data"}, isdbgrid: {skip: "does not return user data"}, - isMaster: {skip: "does not return user data"}, killCursors: {skip: "does not return user data"}, killAllSessions: {skip: "does not return user data"}, killAllSessionsByPattern: {skip: "does not return user data"}, diff --git a/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js b/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js index 5d4951c972e..dcf4313395e 100644 --- a/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js +++ b/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js @@ -203,11 +203,11 @@ let testCases = { grantRolesToRole: {skip: "primary only"}, grantRolesToUser: {skip: "primary only"}, handshake: {skip: "does not return user data"}, + hello: {skip: "does not return user data"}, hostInfo: {skip: "does not return user data"}, insert: {skip: "primary only"}, invalidateUserCache: {skip: "does not return user data"}, isdbgrid: {skip: "does not return user data"}, - isMaster: {skip: "does not return user data"}, killAllSessions: {skip: "does not return user data"}, killAllSessionsByPattern: {skip: "does not return user data"}, killCursors: {skip: "does not return user data"}, diff --git a/src/mongo/db/repl/replication_info.cpp b/src/mongo/db/repl/replication_info.cpp index 617ac34bfc2..8685a30ecb8 100644 --- a/src/mongo/db/repl/replication_info.cpp +++ b/src/mongo/db/repl/replication_info.cpp @@ -33,6 +33,7 @@ #include <list> #include <vector> +#include "mongo/base/string_data.h" #include "mongo/bson/util/bson_extract.h" #include "mongo/client/connpool.h" #include "mongo/client/dbclient_connection.h" @@ -81,6 +82,12 @@ using std::unique_ptr; namespace repl { namespace { + +constexpr auto kHelloString = "hello"_sd; +// Aliases for the hello command in order to provide backwards compatibility. +constexpr auto kCamelCaseIsMasterString = "isMaster"_sd; +constexpr auto kLowerCaseIsMasterString = "ismaster"_sd; + /** * Appends replication-related fields to the isMaster response. Returns the topology version that * was included in the response. @@ -292,9 +299,11 @@ public: } } oplogInfoServerStatus; -class CmdIsMaster final : public BasicCommandWithReplyBuilderInterface { +class CmdHello final : public BasicCommandWithReplyBuilderInterface { public: - CmdIsMaster() : BasicCommandWithReplyBuilderInterface("isMaster", "ismaster") {} + CmdHello() + : BasicCommandWithReplyBuilderInterface( + kHelloString, {kCamelCaseIsMasterString, kLowerCaseIsMasterString}) {} bool requiresAuth() const final { return false; @@ -552,7 +561,7 @@ public: return true; } -} cmdismaster; +} cmdhello; OpCounterServerStatusSection replOpCounterServerStatusSection("opcountersRepl", &replOpCounters); diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp index 1a4c7fdf239..b14d1c88f38 100644 --- a/src/mongo/db/service_entry_point_common.cpp +++ b/src/mongo/db/service_entry_point_common.cpp @@ -1379,7 +1379,7 @@ DbResponse receivedCommands(OperationContext* opCtx, const auto session = opCtx->getClient()->session(); if (session) { - if (!opCtx->isExhaust() || c->getName() != "isMaster"_sd) { + if (!opCtx->isExhaust() || c->getName() != "hello"_sd) { InExhaustIsMaster::get(session.get())->setInExhaustIsMaster(false); } } @@ -1716,8 +1716,7 @@ DbResponse ServiceEntryPointCommon::handleRequest(OperationContext* opCtx, if (op == dbMsg || (op == dbQuery && isCommand)) { dbresponse = receivedCommands(opCtx, m, behaviors); // IsMaster should take kMaxAwaitTimeMs at most, log if it takes twice that. - if (auto command = currentOp.getCommand(); - command && (command->getName() == "ismaster" || command->getName() == "isMaster")) { + if (auto command = currentOp.getCommand(); command && (command->getName() == "hello")) { slowMsOverride = 2 * durationCount<Milliseconds>(SingleServerIsMasterMonitor::kMaxAwaitTime); } diff --git a/src/mongo/s/commands/cluster_is_master_cmd.cpp b/src/mongo/s/commands/cluster_is_master_cmd.cpp index a71c0c28ef2..bb0fb7fec3b 100644 --- a/src/mongo/s/commands/cluster_is_master_cmd.cpp +++ b/src/mongo/s/commands/cluster_is_master_cmd.cpp @@ -30,6 +30,7 @@ #include "mongo/platform/basic.h" +#include "mongo/base/string_data.h" #include "mongo/bson/util/bson_extract.h" #include "mongo/db/auth/sasl_mechanism_registry.h" #include "mongo/db/client.h" @@ -66,9 +67,17 @@ MONGO_INITIALIZER(GenerateMongosTopologyVersion)(InitializerContext*) { namespace { -class CmdIsMaster : public BasicCommandWithReplyBuilderInterface { +constexpr auto kHelloString = "hello"_sd; +// Aliases for the hello command in order to provide backwards compatibility. +constexpr auto kCamelCaseIsMasterString = "isMaster"_sd; +constexpr auto kLowerCaseIsMasterString = "ismaster"_sd; + + +class CmdHello : public BasicCommandWithReplyBuilderInterface { public: - CmdIsMaster() : BasicCommandWithReplyBuilderInterface("isMaster", "ismaster") {} + CmdHello() + : BasicCommandWithReplyBuilderInterface( + kHelloString, {kCamelCaseIsMasterString, kLowerCaseIsMasterString}) {} bool supportsWriteConcern(const BSONObj& cmd) const override { return false; @@ -245,7 +254,7 @@ public: return true; } -} isMaster; +} hello; } // namespace } // namespace mongo diff --git a/src/mongo/s/commands/strategy.cpp b/src/mongo/s/commands/strategy.cpp index 7d4e5912fa3..b08550220d6 100644 --- a/src/mongo/s/commands/strategy.cpp +++ b/src/mongo/s/commands/strategy.cpp @@ -354,9 +354,10 @@ MONGO_FAIL_POINT_DEFINE(doNotRefreshShardsOnRetargettingError); */ void runCommand(OperationContext* opCtx, const OpMsgRequest& request, - const NetworkOp opType, + const Message& m, rpc::ReplyBuilderInterface* replyBuilder, BSONObjBuilder* errorBuilder) { + auto const opType = m.operation(); auto const commandName = request.getCommandName(); auto const command = CommandHelpers::findCommand(commandName); if (!command) { @@ -369,6 +370,14 @@ void runCommand(OperationContext* opCtx, return; } + opCtx->setExhaust(OpMsg::isFlagSet(m, OpMsg::kExhaustSupported)); + const auto session = opCtx->getClient()->session(); + if (session) { + if (!opCtx->isExhaust() || command->getName() != "hello"_sd) { + InExhaustIsMaster::get(session.get())->setInExhaustIsMaster(false); + } + } + CommandHelpers::uassertShouldAttemptParse(opCtx, command, request); // Parse the 'maxTimeMS' command option, and use it to set a deadline for the operation on @@ -1038,14 +1047,6 @@ DbResponse Strategy::clientCommand(OperationContext* opCtx, const Message& m) { } }(); - opCtx->setExhaust(OpMsg::isFlagSet(m, OpMsg::kExhaustSupported)); - const auto session = opCtx->getClient()->session(); - if (session) { - if (!opCtx->isExhaust() || request.getCommandName() != "isMaster"_sd) { - InExhaustIsMaster::get(session.get())->setInExhaustIsMaster(false); - } - } - // Execute. std::string db = request.getDatabase().toString(); try { @@ -1055,7 +1056,7 @@ DbResponse Strategy::clientCommand(OperationContext* opCtx, const Message& m) { "Command begin", "db"_attr = db, "headerId"_attr = m.header().getId()); - runCommand(opCtx, request, m.operation(), reply.get(), &errorBuilder); + runCommand(opCtx, request, m, reply.get(), &errorBuilder); LOGV2_DEBUG(22771, 3, "Command end db: {db} msg id: {headerId}", @@ -1273,7 +1274,7 @@ void Strategy::writeOp(OperationContext* opCtx, DbMessage* dbm) { MONGO_UNREACHABLE; } }(), - msg.operation(), + msg, &reply, &errorBuilder); // built objects are ignored } |