diff options
author | Misha Tyulenev <misha@mongodb.com> | 2016-11-09 10:38:56 -0500 |
---|---|---|
committer | Misha Tyulenev <misha@mongodb.com> | 2016-11-09 10:46:12 -0500 |
commit | 9abe003a4307295f4a3785527ac7ff633383b39a (patch) | |
tree | a470f5649776b3232fcca7a96b4f3f460e4643fa | |
parent | e20c8f98eb6e060cc6f46ee60a2683ea7043f1a1 (diff) | |
download | mongo-9abe003a4307295f4a3785527ac7ff633383b39a.tar.gz |
SERVER-26799 do not refresh if RSM is removed from a RSM manager
-rw-r--r-- | src/mongo/base/error_codes.err | 1 | ||||
-rw-r--r-- | src/mongo/client/replica_set_monitor.cpp | 14 | ||||
-rw-r--r-- | src/mongo/client/replica_set_monitor.h | 7 | ||||
-rw-r--r-- | src/mongo/client/replica_set_monitor_manager.cpp | 3 |
4 files changed, 25 insertions, 0 deletions
diff --git a/src/mongo/base/error_codes.err b/src/mongo/base/error_codes.err index c21b810d481..3eb5740d743 100644 --- a/src/mongo/base/error_codes.err +++ b/src/mongo/base/error_codes.err @@ -196,6 +196,7 @@ error_code("BalancerInterrupted", 194) error_code("ViewPipelineMaxSizeExceeded", 195) error_code("InvalidIndexSpecificationOption", 197) error_code("OBSOLETE_ReceivedOpReplyMessage", 198) +error_code("ReplicaSetMonitorRemoved", 199) # Non-sequential error codes (for compatibility only) error_code("SocketException", 9001) diff --git a/src/mongo/client/replica_set_monitor.cpp b/src/mongo/client/replica_set_monitor.cpp index d27cd68d162..c64c4280424 100644 --- a/src/mongo/client/replica_set_monitor.cpp +++ b/src/mongo/client/replica_set_monitor.cpp @@ -233,6 +233,11 @@ void ReplicaSetMonitor::_refresh(const CallbackArgs& cbArgs) { { // reschedule itself invariant(_executor); + if (_isRemovedFromManager.load()) { // already removed so no need to refresh + LOG(1) << "Stopping refresh for replica set " << getName() << " because its removed"; + return; + } + stdx::lock_guard<stdx::mutex> lk(_mutex); std::weak_ptr<ReplicaSetMonitor> that(shared_from_this()); auto status = _executor->scheduleWorkAt(_executor->now() + kRefreshPeriod, @@ -260,6 +265,11 @@ void ReplicaSetMonitor::_refresh(const CallbackArgs& cbArgs) { StatusWith<HostAndPort> ReplicaSetMonitor::getHostOrRefresh(const ReadPreferenceSetting& criteria, Milliseconds maxWait) { + if (_isRemovedFromManager.load()) { + return Status(ErrorCodes::ReplicaSetMonitorRemoved, + str::stream() << "ReplicaSetMonitor for set " << getName() << " is removed"); + } + { // Fast path, for the failure-free case stdx::lock_guard<stdx::mutex> lk(_state->mutex); @@ -453,6 +463,10 @@ bool ReplicaSetMonitor::isKnownToHaveGoodPrimary() const { return false; } +void ReplicaSetMonitor::markAsRemoved() { + _isRemovedFromManager.store(true); +} + Refresher::Refresher(const SetStatePtr& setState) : _set(setState), _scan(setState->currentScan), _startedNewScan(false) { if (_scan) diff --git a/src/mongo/client/replica_set_monitor.h b/src/mongo/client/replica_set_monitor.h index e83f41e4556..7b8f602cbce 100644 --- a/src/mongo/client/replica_set_monitor.h +++ b/src/mongo/client/replica_set_monitor.h @@ -36,6 +36,7 @@ #include "mongo/base/disallow_copying.h" #include "mongo/base/string_data.h" #include "mongo/executor/task_executor.h" +#include "mongo/platform/atomic_word.h" #include "mongo/stdx/functional.h" #include "mongo/util/net/hostandport.h" #include "mongo/util/time_support.h" @@ -164,6 +165,11 @@ public: bool isKnownToHaveGoodPrimary() const; /** + * Marks the instance as removed to exit refresh sooner. + */ + void markAsRemoved(); + + /** * Creates a new ReplicaSetMonitor, if it doesn't already exist. */ static std::shared_ptr<ReplicaSetMonitor> createIfNeeded(const std::string& name, @@ -262,6 +268,7 @@ private: const SetStatePtr _state; executor::TaskExecutor* _executor; + AtomicBool _isRemovedFromManager{false}; }; diff --git a/src/mongo/client/replica_set_monitor_manager.cpp b/src/mongo/client/replica_set_monitor_manager.cpp index 555d8174b3f..6a463dbf29e 100644 --- a/src/mongo/client/replica_set_monitor_manager.cpp +++ b/src/mongo/client/replica_set_monitor_manager.cpp @@ -124,6 +124,9 @@ void ReplicaSetMonitorManager::removeMonitor(StringData setName) { stdx::lock_guard<stdx::mutex> lk(_mutex); ReplicaSetMonitorsMap::const_iterator it = _monitors.find(setName); if (it != _monitors.end()) { + if (auto monitor = it->second.lock()) { + monitor->markAsRemoved(); + } _monitors.erase(it); log() << "Removed ReplicaSetMonitor for replica set " << setName; } |