diff options
9 files changed, 35 insertions, 1 deletions
diff --git a/src/mongo/client/remote_command_targeter.h b/src/mongo/client/remote_command_targeter.h index c345f8b2c9f..8cf912ba98b 100644 --- a/src/mongo/client/remote_command_targeter.h +++ b/src/mongo/client/remote_command_targeter.h @@ -66,6 +66,13 @@ public: */ virtual StatusWith<HostAndPort> findHost(const ReadPreferenceSetting& readPref) = 0; + /** + * Reports to the targeter that a NotMaster response was received when communicating with + * "host', and so it should update its bookkeeping to avoid giving out the host again on a + * subsequent request for the primary. + */ + virtual void markHostNotMaster(const HostAndPort& host) = 0; + protected: RemoteCommandTargeter() = default; }; diff --git a/src/mongo/client/remote_command_targeter_factory_mock.cpp b/src/mongo/client/remote_command_targeter_factory_mock.cpp index 1ed1c11cbc6..8029b5b4c6c 100644 --- a/src/mongo/client/remote_command_targeter_factory_mock.cpp +++ b/src/mongo/client/remote_command_targeter_factory_mock.cpp @@ -51,6 +51,10 @@ public: return _mock->findHost(readPref); } + void markHostNotMaster(const HostAndPort& host) override { + _mock->markHostNotMaster(host); + } + private: const std::shared_ptr<RemoteCommandTargeter> _mock; }; diff --git a/src/mongo/client/remote_command_targeter_mock.cpp b/src/mongo/client/remote_command_targeter_mock.cpp index d09bdc36e8f..38ade7dd09b 100644 --- a/src/mongo/client/remote_command_targeter_mock.cpp +++ b/src/mongo/client/remote_command_targeter_mock.cpp @@ -55,6 +55,8 @@ StatusWith<HostAndPort> RemoteCommandTargeterMock::findHost(const ReadPreference return _findHostReturnValue; } +void RemoteCommandTargeterMock::markHostNotMaster(const HostAndPort& host) {} + void RemoteCommandTargeterMock::setConnectionStringReturnValue(const ConnectionString returnValue) { _connectionStringReturnValue = std::move(returnValue); } diff --git a/src/mongo/client/remote_command_targeter_mock.h b/src/mongo/client/remote_command_targeter_mock.h index 443d7cb68f8..3293300ce5d 100644 --- a/src/mongo/client/remote_command_targeter_mock.h +++ b/src/mongo/client/remote_command_targeter_mock.h @@ -56,6 +56,11 @@ public: StatusWith<HostAndPort> findHost(const ReadPreferenceSetting& readPref) override; /** + * No-op for the mock. + */ + void markHostNotMaster(const HostAndPort& host) override; + + /** * Sets the return value for the next call to connectionString. */ void setConnectionStringReturnValue(const ConnectionString returnValue); diff --git a/src/mongo/client/remote_command_targeter_rs.cpp b/src/mongo/client/remote_command_targeter_rs.cpp index 2870215dfc2..cbaaee553ef 100644 --- a/src/mongo/client/remote_command_targeter_rs.cpp +++ b/src/mongo/client/remote_command_targeter_rs.cpp @@ -78,4 +78,10 @@ StatusWith<HostAndPort> RemoteCommandTargeterRS::findHost(const ReadPreferenceSe return hostAndPort; } +void RemoteCommandTargeterRS::markHostNotMaster(const HostAndPort& host) { + invariant(_rsMonitor); + + _rsMonitor->failedHost(host); +} + } // namespace mongo diff --git a/src/mongo/client/remote_command_targeter_rs.h b/src/mongo/client/remote_command_targeter_rs.h index 8e849fbf9aa..00ece641ef8 100644 --- a/src/mongo/client/remote_command_targeter_rs.h +++ b/src/mongo/client/remote_command_targeter_rs.h @@ -54,6 +54,8 @@ public: StatusWith<HostAndPort> findHost(const ReadPreferenceSetting& readPref) override; + void markHostNotMaster(const HostAndPort& host) override; + private: // Name of the replica set which this targeter maintains const std::string _rsName; diff --git a/src/mongo/client/remote_command_targeter_standalone.cpp b/src/mongo/client/remote_command_targeter_standalone.cpp index e1f7eac46ef..cfb06e38a18 100644 --- a/src/mongo/client/remote_command_targeter_standalone.cpp +++ b/src/mongo/client/remote_command_targeter_standalone.cpp @@ -47,4 +47,8 @@ StatusWith<HostAndPort> RemoteCommandTargeterStandalone::findHost( return _hostAndPort; } +void RemoteCommandTargeterStandalone::markHostNotMaster(const HostAndPort& host) { + dassert(host == _hostAndPort); +} + } // namespace mongo diff --git a/src/mongo/client/remote_command_targeter_standalone.h b/src/mongo/client/remote_command_targeter_standalone.h index a7bbad1429e..79b29a93556 100644 --- a/src/mongo/client/remote_command_targeter_standalone.h +++ b/src/mongo/client/remote_command_targeter_standalone.h @@ -45,6 +45,8 @@ public: StatusWith<HostAndPort> findHost(const ReadPreferenceSetting& readPref) override; + void markHostNotMaster(const HostAndPort& host) override; + private: const HostAndPort _hostAndPort; }; diff --git a/src/mongo/s/client/shard_registry.cpp b/src/mongo/s/client/shard_registry.cpp index bf7a9e74b15..5b6b497a8e7 100644 --- a/src/mongo/s/client/shard_registry.cpp +++ b/src/mongo/s/client/shard_registry.cpp @@ -366,7 +366,9 @@ StatusWith<BSONObj> ShardRegistry::runCommandWithNotMasterRetries(const ShardId& } Status commandStatus = getStatusFromCommandResult(response.getValue()); - if (ErrorCodes::NotMaster == commandStatus) { + if (ErrorCodes::NotMaster == commandStatus || + ErrorCodes::NotMasterNoSlaveOkCode == commandStatus) { + targeter->markHostNotMaster(target.getValue()); if (i == kNotMasterNumRetries - 1) { // If we're out of retries don't bother sleeping, just return. return commandStatus; |