summaryrefslogtreecommitdiff
path: root/src/mongo/client/replica_set_monitor_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/client/replica_set_monitor_manager.cpp')
-rw-r--r--src/mongo/client/replica_set_monitor_manager.cpp48
1 files changed, 26 insertions, 22 deletions
diff --git a/src/mongo/client/replica_set_monitor_manager.cpp b/src/mongo/client/replica_set_monitor_manager.cpp
index c440f5b0b8f..52db50f277c 100644
--- a/src/mongo/client/replica_set_monitor_manager.cpp
+++ b/src/mongo/client/replica_set_monitor_manager.cpp
@@ -72,8 +72,8 @@ const auto getGlobalRSMMonitorManager =
Status ReplicaSetMonitorManagerNetworkConnectionHook::validateHost(
const HostAndPort& remoteHost,
- const BSONObj& helloRequest,
- const executor::RemoteCommandResponse& helloReply) {
+ const BSONObj& isMasterRequest,
+ const executor::RemoteCommandResponse& isMasterReply) {
auto monitor = ReplicaSetMonitorManager::get()->getMonitorForHost(remoteHost);
if (!monitor) {
return Status::OK();
@@ -85,19 +85,19 @@ Status ReplicaSetMonitorManagerNetworkConnectionHook::validateHost(
auto publisher = streamableMonitor->getEventsPublisher();
if (publisher) {
try {
- if (helloReply.status.isOK()) {
+ if (isMasterReply.status.isOK()) {
publisher->onServerHandshakeCompleteEvent(
- *helloReply.elapsed, remoteHost, helloReply.data);
+ *isMasterReply.elapsed, remoteHost, isMasterReply.data);
} else {
publisher->onServerHandshakeFailedEvent(
- remoteHost, helloReply.status, helloReply.data);
+ remoteHost, isMasterReply.status, isMasterReply.data);
}
} catch (const DBException& exception) {
LOGV2_ERROR(4712101,
"An error occurred publishing a ReplicaSetMonitor handshake event",
"error"_attr = exception.toStatus(),
"replicaSet"_attr = monitor->getName(),
- "handshakeStatus"_attr = helloReply.status);
+ "handshakeStatus"_attr = isMasterReply.status);
return exception.toStatus();
}
}
@@ -141,6 +141,10 @@ void ReplicaSetMonitorManager::_setupTaskExecutorAndStatsInLock() {
return;
}
+ if (!_stats) {
+ _stats = std::make_shared<ReplicaSetMonitorManagerStats>();
+ }
+
// construct task executor
auto hookList = std::make_unique<rpc::EgressMetadataHookList>();
auto networkConnectionHook = std::make_unique<ReplicaSetMonitorManagerNetworkConnectionHook>();
@@ -219,6 +223,7 @@ shared_ptr<ReplicaSetMonitor> ReplicaSetMonitorManager::getMonitorForHost(const
vector<string> ReplicaSetMonitorManager::getAllSetNames() const {
vector<string> allNames;
+
stdx::lock_guard<Latch> lk(_mutex);
for (const auto& entry : _monitors) {
@@ -312,31 +317,30 @@ void ReplicaSetMonitorManager::removeAllMonitors() {
}
void ReplicaSetMonitorManager::report(BSONObjBuilder* builder, bool forFTDC) {
- std::vector<std::shared_ptr<ReplicaSetMonitor>> monitors;
- int numMonitorsCreated;
- // Gather relevant data under the lock. Separate out writing it to BSON.
- {
- stdx::lock_guard lk(_mutex);
- _doGarbageCollectionLocked(lk);
- for (const auto& [_, weakMonitor] : _monitors) {
- if (auto monitor = weakMonitor.lock())
- monitors.push_back(std::move(monitor));
- }
- numMonitorsCreated = _numMonitorsCreated;
- }
- // Now write out the data.
- builder->appendNumber("numReplicaSetMonitorsCreated", numMonitorsCreated);
+ // Don't hold _mutex the whole time to avoid ever taking a monitor's mutex while holding the
+ // manager's mutex. Otherwise we could get a deadlock between the manager's, monitor's, and
+ // ShardRegistry's mutex due to the ReplicaSetMonitor's AsynchronousConfigChangeHook
+ // potentially calling ShardRegistry::updateConfigServerConnectionString.
+ auto setNames = getAllSetNames();
+
+ builder->appendNumber("numReplicaSetMonitorsCreated", _numMonitorsCreated);
{
BSONObjBuilder setStats(
builder->subobjStart(forFTDC ? "replicaSetPingTimesMillis" : "replicaSets"));
- for (const auto& monitor : monitors) {
+ for (const auto& setName : setNames) {
+ auto monitor = getMonitor(setName);
+ if (!monitor) {
+ continue;
+ }
monitor->appendInfo(setStats, forFTDC);
}
}
- _stats->report(builder, forFTDC);
+ if (_stats) {
+ _stats->report(builder, forFTDC);
+ }
}
std::shared_ptr<executor::TaskExecutor> ReplicaSetMonitorManager::getExecutor() {