diff options
Diffstat (limited to 'src/mongo/client/replica_set_monitor.h')
-rw-r--r-- | src/mongo/client/replica_set_monitor.h | 272 |
1 files changed, 14 insertions, 258 deletions
diff --git a/src/mongo/client/replica_set_monitor.h b/src/mongo/client/replica_set_monitor.h index 44b9a2504d1..1fa5f737ae9 100644 --- a/src/mongo/client/replica_set_monitor.h +++ b/src/mongo/client/replica_set_monitor.h @@ -34,9 +34,9 @@ #include <set> #include <string> -#include "mongo/base/string_data.h" #include "mongo/client/mongo_uri.h" #include "mongo/client/replica_set_change_notifier.h" +#include "mongo/client/replica_set_monitor_interface.h" #include "mongo/executor/task_executor.h" #include "mongo/util/concurrency/with_lock.h" #include "mongo/util/duration.h" @@ -44,136 +44,24 @@ #include "mongo/util/time_support.h" namespace mongo { - -class BSONObj; -class ReplicaSetMonitor; -class ReplicaSetMonitorTest; -struct ReadPreferenceSetting; -typedef std::shared_ptr<ReplicaSetMonitor> ReplicaSetMonitorPtr; - /** - * Holds state about a replica set and provides a means to refresh the local view. - * All methods perform the required synchronization to allow callers from multiple threads. + * An abstract class, defines the external interface for static ReplicaSetMonitor methods and + * provides a means to refresh the local view. + * A ReplicaSetMonitor holds a state about the replica set and provides a means to refresh the local + * view. All methods perform the required synchronization to allow callers from multiple threads. */ -class ReplicaSetMonitor { - ReplicaSetMonitor(const ReplicaSetMonitor&) = delete; - ReplicaSetMonitor& operator=(const ReplicaSetMonitor&) = delete; - +class ReplicaSetMonitor : public ReplicaSetMonitorInterface { public: - class Refresher; - - static constexpr auto kExpeditedRefreshPeriod = Milliseconds(500); - static constexpr auto kCheckTimeout = Seconds(5); - - /** - * Initializes local state from a MongoURI. - */ - ReplicaSetMonitor(const MongoURI& uri); - - /** - * Schedules the initial refresh task into task executor. - */ - void init(); - - /** - * Ends any ongoing refreshes. - */ - void drop(); + virtual ~ReplicaSetMonitor() = default; /** - * Returns a host matching the given read preference or an error, if no host matches. - * - * @param readPref Read preference to match against - * @param maxWait If no host is readily available, which matches the specified read preference, - * wait for one to become available for up to the specified time and periodically refresh - * the view of the set. The call may return with an error earlier than the specified value, - * if none of the known hosts for the set are reachable within some number of attempts. - * Note that if a maxWait of 0ms is specified, this method may still attempt to contact - * every host in the replica set up to one time. - * - * Known errors are: - * FailedToSatisfyReadPreference, if node cannot be found, which matches the read preference. - */ - SemiFuture<HostAndPort> getHostOrRefresh(const ReadPreferenceSetting& readPref, - Milliseconds maxWait = kDefaultFindHostTimeout); - - SemiFuture<std::vector<HostAndPort>> getHostsOrRefresh( - const ReadPreferenceSetting& readPref, Milliseconds maxWait = kDefaultFindHostTimeout); - - /** - * Returns the host we think is the current master or uasserts. - * - * This is a thin wrapper around getHostOrRefresh so this will also refresh our view if we - * don't think there is a master at first. The main difference is that this will uassert - * rather than returning an empty HostAndPort. - */ - HostAndPort getMasterOrUassert(); - - /** - * Notifies this Monitor that a host has failed because of the specified error 'status' and - * should be considered down. + * Defaults to false, meaning that if multiple hosts meet a criteria we pick one at random. + * This is required by the replica set driver spec. Set this to true in tests that need host + * selection to be deterministic. * - * Call this when you get a connection error. If you get an error while trying to refresh our - * view of a host, call Refresher::failedHost instead because it bypasses taking the monitor's - * mutex. - */ - void failedHost(const HostAndPort& host, const Status& status); - - /** - * Returns true if this node is the master based ONLY on local data. Be careful, return may - * be stale. - */ - bool isPrimary(const HostAndPort& host) const; - - /** - * Returns true if host is part of this set and is considered up (meaning it can accept - * queries). - */ - bool isHostUp(const HostAndPort& host) const; - - /** - * Returns the minimum wire version supported across the replica set. - */ - int getMinWireVersion() const; - - /** - * Returns the maximum wire version supported across the replica set. - */ - int getMaxWireVersion() const; - - /** - * The name of the set. - */ - std::string getName() const; - - /** - * Returns a std::string with the format name/server1,server2. - * If name is empty, returns just comma-separated list of servers. - * It IS updated to reflect the current members of the set. - */ - std::string getServerAddress() const; - - /** - * Returns the URI that was used to construct this monitor. - * It IS NOT updated to reflect the current members of the set. - */ - const MongoURI& getOriginalUri() const; - - /** - * Is server part of this set? Uses only cached information. - */ - bool contains(const HostAndPort& server) const; - - /** - * Writes information about our cached view of the set to a BSONObjBuilder. If - * forFTDC, trim to minimize its size for full-time diagnostic data capture. - */ - void appendInfo(BSONObjBuilder& b, bool forFTDC = false) const; - - /** - * Returns true if the monitor knows a usable primary from it's interal view. + * NOTE: Used by unit-tests only. */ - bool isKnownToHaveGoodPrimary() const; + static bool useDeterministicHostSelection; /** * Creates a new ReplicaSetMonitor, if it doesn't already exist. @@ -210,145 +98,13 @@ public: static void cleanup(); /** - * Use these to speed up tests by disabling the sleep-and-retry loops and cause errors to be - * reported immediately. - */ - static void disableRefreshRetries_forTest(); - - /** * Permanently stops all monitoring on replica sets. */ static void shutdown(); - /** - * Returns the refresh period that is given to all new SetStates. - */ - static Seconds getDefaultRefreshPeriod(); - - // - // internal types (defined in replica_set_monitor_internal.h) - // - - struct IsMasterReply; - struct ScanState; - struct SetState; - typedef std::shared_ptr<ScanState> ScanStatePtr; - typedef std::shared_ptr<SetState> SetStatePtr; - - /** - * Allows tests to set initial conditions and introspect the current state. - */ - explicit ReplicaSetMonitor(const SetStatePtr& initialState); - ~ReplicaSetMonitor(); - - /** - * The default timeout, which will be used for finding a replica set host if the caller does - * not explicitly specify it. - */ - static const Seconds kDefaultFindHostTimeout; - - /** - * Defaults to false, meaning that if multiple hosts meet a criteria we pick one at random. - * This is required by the replica set driver spec. Set this to true in tests that need host - * selection to be deterministic. - * - * NOTE: Used by unit-tests only. - */ - static bool useDeterministicHostSelection; - - /** - * This is for use in tests using MockReplicaSet to ensure that a full scan completes before - * continuing. - */ - void runScanForMockReplicaSet(); - -private: - Future<std::vector<HostAndPort>> _getHostsOrRefresh(const ReadPreferenceSetting& readPref, - Milliseconds maxWait); - /** - * If no scan is in-progress, this function is responsible for setting up a new scan. Otherwise, - * does nothing. - */ - static void _ensureScanInProgress(const SetStatePtr&); - - const SetStatePtr _state; -}; - - -/** - * Refreshes the local view of a replica set. - * - * All logic related to choosing the hosts to contact and updating the SetState based on replies - * lives in this class. Use of this class should always be guarded by SetState::mutex unless in - * single-threaded use by ReplicaSetMonitorTest. - */ -class ReplicaSetMonitor::Refresher { -public: - explicit Refresher(const SetStatePtr& setState); - - struct NextStep { - enum StepKind { - CONTACT_HOST, /// Contact the returned host - WAIT, /// Wait on condition variable and try again. - DONE, /// No more hosts to contact in this Refresh round - }; - - explicit NextStep(StepKind step, const HostAndPort& host = HostAndPort()) - : step(step), host(host) {} - - StepKind step; - HostAndPort host; - }; - - /** - * Returns the next step to take. - * - * By calling this, you promise to call receivedIsMaster or failedHost if the NextStep is - * CONTACT_HOST. - */ - NextStep getNextStep(); - - /** - * Call this if a host returned from getNextStep successfully replied to an isMaster call. - * Negative latencyMicros are ignored. - */ - void receivedIsMaster(const HostAndPort& from, int64_t latencyMicros, const BSONObj& reply); - - /** - * Call this if a host returned from getNextStep failed to reply to an isMaster call. - */ - void failedHost(const HostAndPort& host, const Status& status); - - /** - * Starts a new scan over the hosts in set. - */ - void startNewScan(); - - /** - * First, checks that the "reply" is not from a stale primary by comparing the electionId of - * "reply" to the maxElectionId recorded by the SetState and returns OK status if "reply" - * belongs to a non-stale primary. Otherwise returns a failed status. - * - * The 'from' parameter specifies the node from which the response is received. - * - * Updates _set and _scan based on set-membership information from a master. - * Applies _scan->unconfirmedReplies to confirmed nodes. - * Does not update this host's node in _set->nodes. - */ - Status receivedIsMasterFromMaster(const HostAndPort& from, const IsMasterReply& reply); - - /** - * Schedules isMaster requests to all hosts that currently need to be contacted. - * Does nothing if requests have already been sent to all known hosts. - */ - void scheduleNetworkRequests(); - - void scheduleIsMaster(const HostAndPort& host); + static void disableRefreshRetries_forTest(); -private: - // Both pointers are never NULL - SetStatePtr _set; - ScanStatePtr _scan; // May differ from _set->currentScan if a new scan has started. + static bool areRefreshRetriesDisabledForTest(); }; } // namespace mongo |