summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl/topology_coordinator_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/repl/topology_coordinator_impl.h')
-rw-r--r--src/mongo/db/repl/topology_coordinator_impl.h744
1 files changed, 370 insertions, 374 deletions
diff --git a/src/mongo/db/repl/topology_coordinator_impl.h b/src/mongo/db/repl/topology_coordinator_impl.h
index cfc8e88e5f1..c6dd3e26533 100644
--- a/src/mongo/db/repl/topology_coordinator_impl.h
+++ b/src/mongo/db/repl/topology_coordinator_impl.h
@@ -43,389 +43,385 @@
namespace mongo {
- class OperationContext;
+class OperationContext;
namespace repl {
+/**
+ * Represents a latency measurement for each replica set member based on heartbeat requests.
+ * The measurement is an average weighted 80% to the old value, and 20% to the new value.
+ *
+ * Also stores information about heartbeat progress and retries.
+ */
+class PingStats {
+public:
+ PingStats();
+
/**
- * Represents a latency measurement for each replica set member based on heartbeat requests.
- * The measurement is an average weighted 80% to the old value, and 20% to the new value.
+ * Records that a new heartbeat request started at "now".
*
- * Also stores information about heartbeat progress and retries.
+ * This resets the failure count used in determining whether the next request to a target
+ * should be a retry or a regularly scheduled heartbeat message.
*/
- class PingStats {
- public:
- PingStats();
-
- /**
- * Records that a new heartbeat request started at "now".
- *
- * This resets the failure count used in determining whether the next request to a target
- * should be a retry or a regularly scheduled heartbeat message.
- */
- void start(Date_t now);
-
- /**
- * Records that a heartbeat request completed successfully, and that "millis" milliseconds
- * were spent for a single network roundtrip plus remote processing time.
- */
- void hit(int millis);
-
- /**
- * Records that a heartbeat request failed.
- */
- void miss();
-
- /**
- * Gets the number of hit() calls.
- */
- unsigned int getCount() const { return count; }
-
- /**
- * Gets the weighted average round trip time for heartbeat messages to the target.
- */
- unsigned int getMillis() const { return value; }
-
- /**
- * Gets the date at which start() was last called, which is used to determine if
- * a heartbeat should be retried or if the time limit has expired.
- */
- Date_t getLastHeartbeatStartDate() const { return _lastHeartbeatStartDate; }
-
- /**
- * Gets the number of failures since start() was last called.
- *
- * This value is incremented by calls to miss(), cleared by calls to start() and
- * set to the maximum possible value by calls to hit().
- */
- int getNumFailuresSinceLastStart() const { return _numFailuresSinceLastStart; }
-
- private:
- unsigned int count;
- unsigned int value;
- Date_t _lastHeartbeatStartDate;
- int _numFailuresSinceLastStart;
- };
+ void start(Date_t now);
- class TopologyCoordinatorImpl : public TopologyCoordinator {
- public:
- /**
- * Constructs a Topology Coordinator object.
- * @param maxSyncSourceLagSecs a sync source is re-evaluated after it lags behind further
- * than this amount.
- **/
- TopologyCoordinatorImpl(Seconds maxSyncSourceLagSecs);
-
- ////////////////////////////////////////////////////////////
- //
- // Implementation of TopologyCoordinator interface
- //
- ////////////////////////////////////////////////////////////
-
- virtual Role getRole() const;
- virtual MemberState getMemberState() const;
- virtual HostAndPort getSyncSourceAddress() const;
- virtual std::vector<HostAndPort> getMaybeUpHostAndPorts() const;
- virtual int getMaintenanceCount() const;
- virtual long long getTerm() const;
- virtual bool updateTerm(long long term);
- virtual void setForceSyncSourceIndex(int index);
- virtual HostAndPort chooseNewSyncSource(Date_t now,
- const OpTime& lastOpApplied);
- virtual void blacklistSyncSource(const HostAndPort& host, Date_t until);
- virtual void unblacklistSyncSource(const HostAndPort& host, Date_t now);
- virtual void clearSyncSourceBlacklist();
- virtual bool shouldChangeSyncSource(const HostAndPort& currentSource, Date_t now) const;
- virtual bool becomeCandidateIfStepdownPeriodOverAndSingleNodeSet(Date_t now);
- virtual void setElectionSleepUntil(Date_t newTime);
- virtual void setFollowerMode(MemberState::MS newMode);
- virtual void adjustMaintenanceCountBy(int inc);
- virtual void prepareSyncFromResponse(const ReplicationExecutor::CallbackArgs& data,
- const HostAndPort& target,
- const OpTime& lastOpApplied,
- BSONObjBuilder* response,
- Status* result);
- virtual void prepareFreshResponse(const ReplicationCoordinator::ReplSetFreshArgs& args,
- Date_t now,
- const OpTime& lastOpApplied,
- BSONObjBuilder* response,
- Status* result);
- virtual void prepareElectResponse(const ReplicationCoordinator::ReplSetElectArgs& args,
- Date_t now,
- const OpTime& lastOpApplied,
- BSONObjBuilder* response,
- Status* result);
- virtual Status prepareHeartbeatResponse(Date_t now,
- const ReplSetHeartbeatArgs& args,
- const std::string& ourSetName,
- const OpTime& lastOpApplied,
- ReplSetHeartbeatResponse* response);
- virtual Status prepareHeartbeatResponseV1(Date_t now,
- const ReplSetHeartbeatArgsV1& args,
- const std::string& ourSetName,
- const OpTime& lastOpApplied,
- ReplSetHeartbeatResponse* response);
- virtual void prepareStatusResponse(const ReplicationExecutor::CallbackArgs& data,
- Date_t now,
- unsigned uptime,
- const OpTime& lastOpApplied,
- BSONObjBuilder* response,
- Status* result);
- virtual void fillIsMasterForReplSet(IsMasterResponse* response);
- virtual void prepareFreezeResponse(Date_t now, int secs, BSONObjBuilder* response);
- virtual void updateConfig(const ReplicaSetConfig& newConfig,
- int selfIndex,
- Date_t now,
- const OpTime& lastOpApplied);
- virtual std::pair<ReplSetHeartbeatArgs, Milliseconds> prepareHeartbeatRequest(
- Date_t now,
- const std::string& ourSetName,
- const HostAndPort& target);
- virtual std::pair<ReplSetHeartbeatArgsV1, Milliseconds> prepareHeartbeatRequestV1(
- Date_t now,
- const std::string& ourSetName,
- const HostAndPort& target);
- virtual HeartbeatResponseAction processHeartbeatResponse(
- Date_t now,
- Milliseconds networkRoundTripTime,
- const HostAndPort& target,
- const StatusWith<ReplSetHeartbeatResponse>& hbResponse,
- const OpTime& myLastOpApplied);
- virtual bool voteForMyself(Date_t now);
- virtual void processWinElection(OID electionId, Timestamp electionOpTime);
- virtual void processLoseElection();
- virtual bool checkShouldStandForElection(Date_t now, const OpTime& lastOpApplied);
- virtual void setMyHeartbeatMessage(const Date_t now, const std::string& message);
- virtual bool stepDown(Date_t until, bool force, const OpTime& lastOpApplied);
- virtual bool stepDownIfPending();
- virtual Date_t getStepDownTime() const;
- virtual void prepareCursorResponseInfo(BSONObjBuilder* objBuilder,
- const OpTime& lastCommitttedOpTime) const;
- Status processReplSetDeclareElectionWinner(const ReplSetDeclareElectionWinnerArgs& args,
- long long* responseTerm);
- virtual void processReplSetRequestVotes(const ReplSetRequestVotesArgs& args,
- ReplSetRequestVotesResponse* response,
- const OpTime& lastAppliedOpTime);
- virtual void summarizeAsHtml(ReplSetHtmlSummary* output);
- virtual void loadLastVote(const LastVote& lastVote);
- virtual void incrementTerm();
- virtual void voteForMyselfV1();
- virtual long long getTerm();
- virtual void prepareForStepDown();
-
- ////////////////////////////////////////////////////////////
- //
- // Test support methods
- //
- ////////////////////////////////////////////////////////////
-
- // Changes _memberState to newMemberState. Only for testing.
- void changeMemberState_forTest(const MemberState& newMemberState,
- const Timestamp& electionTime = Timestamp(0,0));
-
- // Sets "_electionTime" to "newElectionTime". Only for testing.
- void _setElectionTime(const Timestamp& newElectionTime);
-
- // Sets _currentPrimaryIndex to the given index. Should only be used in unit tests!
- // TODO(spencer): Remove this once we can easily call for an election in unit tests to
- // set the current primary.
- void _setCurrentPrimaryForTest(int primaryIndex);
-
- // Returns _electionTime. Only used in unittests.
- Timestamp getElectionTime() const;
-
- // Returns _electionId. Only used in unittests.
- OID getElectionId() const;
-
- // Returns _currentPrimaryIndex. Only used in unittests.
- int getCurrentPrimaryIndex() const;
-
- private:
-
- enum UnelectableReason {
- None = 0,
- CannotSeeMajority = 1 << 0,
- NotCloseEnoughToLatestOptime = 1 << 1,
- ArbiterIAm = 1 << 2,
- NotSecondary = 1 << 3,
- NoPriority = 1 << 4,
- StepDownPeriodActive = 1 << 5,
- NoData = 1 << 6,
- NotInitialized = 1 << 7,
- VotedTooRecently = 1 << 8,
- RefusesToStand = 1 << 9
- };
- typedef int UnelectableReasonMask;
-
- // Returns the number of heartbeat pings which have occurred.
- int _getTotalPings();
-
- // Returns the current "ping" value for the given member by their address
- int _getPing(const HostAndPort& host);
-
- // Determines if we will veto the member specified by "args.id", given that the last op
- // we have applied locally is "lastOpApplied".
- // If we veto, the errmsg will be filled in with a reason
- bool _shouldVetoMember(const ReplicationCoordinator::ReplSetFreshArgs& args,
- const Date_t& now,
- const OpTime& lastOpApplied,
- std::string* errmsg) const;
-
- // Returns the index of the member with the matching id, or -1 if none match.
- int _getMemberIndex(int id) const;
-
- // Sees if a majority number of votes are held by members who are currently "up"
- bool _aMajoritySeemsToBeUp() const;
-
- // Is otherOpTime close enough (within 10 seconds) to the latest known optime to qualify
- // for an election
- bool _isOpTimeCloseEnoughToLatestToElect(const OpTime& otherOpTime,
- const OpTime& ourLastOpApplied) const;
-
- // Returns reason why "self" member is unelectable
- UnelectableReasonMask _getMyUnelectableReason(
- const Date_t now,
- const OpTime& lastOpApplied) const;
-
- // Returns reason why memberIndex is unelectable
- UnelectableReasonMask _getUnelectableReason(
- int memberIndex,
- const OpTime& lastOpApplied) const;
-
- // Returns the nice text of why the node is unelectable
- std::string _getUnelectableReasonString(UnelectableReasonMask ur) const;
-
- // Return true if we are currently primary
- bool _iAmPrimary() const;
-
- // Scans through all members that are 'up' and return the latest known optime.
- OpTime _latestKnownOpTime(const OpTime& ourLastOpApplied) const;
-
- // Scans the electable set and returns the highest priority member index
- int _getHighestPriorityElectableIndex(Date_t now, const OpTime& lastOpApplied) const;
-
- // Returns true if "one" member is higher priority than "two" member
- bool _isMemberHigherPriority(int memberOneIndex, int memberTwoIndex) const;
-
- // Helper shortcut to self config
- const MemberConfig& _selfConfig() const;
-
- // Returns NULL if there is no primary, or the MemberConfig* for the current primary
- const MemberConfig* _currentPrimaryMember() const;
-
- /**
- * Performs updating "_hbdata" and "_currentPrimaryIndex" for processHeartbeatResponse().
- */
- HeartbeatResponseAction _updateHeartbeatDataImpl(
- int updatedConfigIndex,
- const MemberState& originalState,
- Date_t now,
- const OpTime& lastOpApplied);
-
- /**
- * Updates _hbdata based on the newConfig, ensuring that every member in the newConfig
- * has an entry in _hbdata. If any nodes in the newConfig are also present in
- * _currentConfig, copies their heartbeat info into the corresponding entry in the updated
- * _hbdata vector.
- */
- void _updateHeartbeatDataForReconfig(const ReplicaSetConfig& newConfig,
- int selfIndex,
- Date_t now);
-
- void _stepDownSelfAndReplaceWith(int newPrimary);
-
- MemberState _getMyState() const;
-
- /**
- * Looks up the provided member in the blacklist and returns true if the member's blacklist
- * expire time is after 'now'. If the member is found but the expire time is before 'now',
- * the function returns false. If the member is not found in the blacklist, the function
- * returns false.
- **/
- bool _memberIsBlacklisted(const MemberConfig& memberConfig, Date_t now) const;
-
- // This node's role in the replication protocol.
- Role _role;
-
- // This is a unique id that is generated and set each time we transition to PRIMARY, as the
- // result of an election.
- OID _electionId;
- // The time at which the current PRIMARY was elected.
- Timestamp _electionTime;
-
- // This node's election term. The term is used as part of the consensus algorithm to elect
- // and maintain one primary (leader) node in the cluster.
- long long _term = 0;
-
- // the index of the member we currently believe is primary, if one exists, otherwise -1
- int _currentPrimaryIndex;
-
- // the hostandport we are currently syncing from
- // empty if no sync source (we are primary, or we cannot connect to anyone yet)
- HostAndPort _syncSource;
- // These members are not chosen as sync sources for a period of time, due to connection
- // issues with them
- std::map<HostAndPort, Date_t> _syncSourceBlacklist;
- // The next sync source to be chosen, requested via a replSetSyncFrom command
- int _forceSyncSourceIndex;
- // How far this node must fall behind before considering switching sync sources
- Seconds _maxSyncSourceLagSecs;
+ /**
+ * Records that a heartbeat request completed successfully, and that "millis" milliseconds
+ * were spent for a single network roundtrip plus remote processing time.
+ */
+ void hit(int millis);
- // "heartbeat message"
- // sent in requestHeartbeat respond in field "hbm"
- std::string _hbmsg;
- Date_t _hbmsgTime; // when it was logged
-
- // heartbeat msg to send to others; descriptive diagnostic info
- std::string _getHbmsg(Date_t now) const;
-
- int _selfIndex; // this node's index in _members and _currentConfig
-
- ReplicaSetConfig _rsConfig; // The current config, including a vector of MemberConfigs
-
- // heartbeat data for each member. It is guaranteed that this vector will be maintained
- // in the same order as the MemberConfigs in _currentConfig, therefore the member config
- // index can be used to index into this vector as well.
- std::vector<MemberHeartbeatData> _hbdata;
-
- // Indicates that we've received a request to stepdown from PRIMARY (likely via a heartbeat)
- bool _stepDownPending;
+ /**
+ * Records that a heartbeat request failed.
+ */
+ void miss();
- // Time when stepDown command expires
- Date_t _stepDownUntil;
-
- // A time before which this node will not stand for election.
- Date_t _electionSleepUntil;
-
- // The number of calls we have had to enter maintenance mode
- int _maintenanceModeCalls;
-
- // The sub-mode of follower that we are in. Legal values are RS_SECONDARY, RS_RECOVERING,
- // RS_STARTUP2 (initial sync) and RS_ROLLBACK. Only meaningful if _role == Role::follower.
- // Configured via setFollowerMode(). If the sub-mode is RS_SECONDARY, then the effective
- // sub-mode is either RS_SECONDARY or RS_RECOVERING, depending on _maintenanceModeCalls.
- // Rather than accesing this variable direclty, one should use the getMemberState() method,
- // which computes the replica set node state on the fly.
- MemberState::MS _followerMode;
-
- typedef std::map<HostAndPort, PingStats> PingMap;
- // Ping stats for each member by HostAndPort;
- PingMap _pings;
-
- // Last vote info from the election
- struct VoteLease {
-
- static const Seconds leaseTime;
-
- Date_t when;
- int whoId = -1;
- HostAndPort whoHostAndPort;
- } _voteLease;
-
- // V1 last vote info for elections
- LastVote _lastVote;
+ /**
+ * Gets the number of hit() calls.
+ */
+ unsigned int getCount() const {
+ return count;
+ }
+ /**
+ * Gets the weighted average round trip time for heartbeat messages to the target.
+ */
+ unsigned int getMillis() const {
+ return value;
+ }
+
+ /**
+ * Gets the date at which start() was last called, which is used to determine if
+ * a heartbeat should be retried or if the time limit has expired.
+ */
+ Date_t getLastHeartbeatStartDate() const {
+ return _lastHeartbeatStartDate;
+ }
+
+ /**
+ * Gets the number of failures since start() was last called.
+ *
+ * This value is incremented by calls to miss(), cleared by calls to start() and
+ * set to the maximum possible value by calls to hit().
+ */
+ int getNumFailuresSinceLastStart() const {
+ return _numFailuresSinceLastStart;
+ }
+
+private:
+ unsigned int count;
+ unsigned int value;
+ Date_t _lastHeartbeatStartDate;
+ int _numFailuresSinceLastStart;
+};
+
+class TopologyCoordinatorImpl : public TopologyCoordinator {
+public:
+ /**
+ * Constructs a Topology Coordinator object.
+ * @param maxSyncSourceLagSecs a sync source is re-evaluated after it lags behind further
+ * than this amount.
+ **/
+ TopologyCoordinatorImpl(Seconds maxSyncSourceLagSecs);
+
+ ////////////////////////////////////////////////////////////
+ //
+ // Implementation of TopologyCoordinator interface
+ //
+ ////////////////////////////////////////////////////////////
+
+ virtual Role getRole() const;
+ virtual MemberState getMemberState() const;
+ virtual HostAndPort getSyncSourceAddress() const;
+ virtual std::vector<HostAndPort> getMaybeUpHostAndPorts() const;
+ virtual int getMaintenanceCount() const;
+ virtual long long getTerm() const;
+ virtual bool updateTerm(long long term);
+ virtual void setForceSyncSourceIndex(int index);
+ virtual HostAndPort chooseNewSyncSource(Date_t now, const OpTime& lastOpApplied);
+ virtual void blacklistSyncSource(const HostAndPort& host, Date_t until);
+ virtual void unblacklistSyncSource(const HostAndPort& host, Date_t now);
+ virtual void clearSyncSourceBlacklist();
+ virtual bool shouldChangeSyncSource(const HostAndPort& currentSource, Date_t now) const;
+ virtual bool becomeCandidateIfStepdownPeriodOverAndSingleNodeSet(Date_t now);
+ virtual void setElectionSleepUntil(Date_t newTime);
+ virtual void setFollowerMode(MemberState::MS newMode);
+ virtual void adjustMaintenanceCountBy(int inc);
+ virtual void prepareSyncFromResponse(const ReplicationExecutor::CallbackArgs& data,
+ const HostAndPort& target,
+ const OpTime& lastOpApplied,
+ BSONObjBuilder* response,
+ Status* result);
+ virtual void prepareFreshResponse(const ReplicationCoordinator::ReplSetFreshArgs& args,
+ Date_t now,
+ const OpTime& lastOpApplied,
+ BSONObjBuilder* response,
+ Status* result);
+ virtual void prepareElectResponse(const ReplicationCoordinator::ReplSetElectArgs& args,
+ Date_t now,
+ const OpTime& lastOpApplied,
+ BSONObjBuilder* response,
+ Status* result);
+ virtual Status prepareHeartbeatResponse(Date_t now,
+ const ReplSetHeartbeatArgs& args,
+ const std::string& ourSetName,
+ const OpTime& lastOpApplied,
+ ReplSetHeartbeatResponse* response);
+ virtual Status prepareHeartbeatResponseV1(Date_t now,
+ const ReplSetHeartbeatArgsV1& args,
+ const std::string& ourSetName,
+ const OpTime& lastOpApplied,
+ ReplSetHeartbeatResponse* response);
+ virtual void prepareStatusResponse(const ReplicationExecutor::CallbackArgs& data,
+ Date_t now,
+ unsigned uptime,
+ const OpTime& lastOpApplied,
+ BSONObjBuilder* response,
+ Status* result);
+ virtual void fillIsMasterForReplSet(IsMasterResponse* response);
+ virtual void prepareFreezeResponse(Date_t now, int secs, BSONObjBuilder* response);
+ virtual void updateConfig(const ReplicaSetConfig& newConfig,
+ int selfIndex,
+ Date_t now,
+ const OpTime& lastOpApplied);
+ virtual std::pair<ReplSetHeartbeatArgs, Milliseconds> prepareHeartbeatRequest(
+ Date_t now, const std::string& ourSetName, const HostAndPort& target);
+ virtual std::pair<ReplSetHeartbeatArgsV1, Milliseconds> prepareHeartbeatRequestV1(
+ Date_t now, const std::string& ourSetName, const HostAndPort& target);
+ virtual HeartbeatResponseAction processHeartbeatResponse(
+ Date_t now,
+ Milliseconds networkRoundTripTime,
+ const HostAndPort& target,
+ const StatusWith<ReplSetHeartbeatResponse>& hbResponse,
+ const OpTime& myLastOpApplied);
+ virtual bool voteForMyself(Date_t now);
+ virtual void processWinElection(OID electionId, Timestamp electionOpTime);
+ virtual void processLoseElection();
+ virtual bool checkShouldStandForElection(Date_t now, const OpTime& lastOpApplied);
+ virtual void setMyHeartbeatMessage(const Date_t now, const std::string& message);
+ virtual bool stepDown(Date_t until, bool force, const OpTime& lastOpApplied);
+ virtual bool stepDownIfPending();
+ virtual Date_t getStepDownTime() const;
+ virtual void prepareCursorResponseInfo(BSONObjBuilder* objBuilder,
+ const OpTime& lastCommitttedOpTime) const;
+ Status processReplSetDeclareElectionWinner(const ReplSetDeclareElectionWinnerArgs& args,
+ long long* responseTerm);
+ virtual void processReplSetRequestVotes(const ReplSetRequestVotesArgs& args,
+ ReplSetRequestVotesResponse* response,
+ const OpTime& lastAppliedOpTime);
+ virtual void summarizeAsHtml(ReplSetHtmlSummary* output);
+ virtual void loadLastVote(const LastVote& lastVote);
+ virtual void incrementTerm();
+ virtual void voteForMyselfV1();
+ virtual long long getTerm();
+ virtual void prepareForStepDown();
+
+ ////////////////////////////////////////////////////////////
+ //
+ // Test support methods
+ //
+ ////////////////////////////////////////////////////////////
+
+ // Changes _memberState to newMemberState. Only for testing.
+ void changeMemberState_forTest(const MemberState& newMemberState,
+ const Timestamp& electionTime = Timestamp(0, 0));
+
+ // Sets "_electionTime" to "newElectionTime". Only for testing.
+ void _setElectionTime(const Timestamp& newElectionTime);
+
+ // Sets _currentPrimaryIndex to the given index. Should only be used in unit tests!
+ // TODO(spencer): Remove this once we can easily call for an election in unit tests to
+ // set the current primary.
+ void _setCurrentPrimaryForTest(int primaryIndex);
+
+ // Returns _electionTime. Only used in unittests.
+ Timestamp getElectionTime() const;
+
+ // Returns _electionId. Only used in unittests.
+ OID getElectionId() const;
+
+ // Returns _currentPrimaryIndex. Only used in unittests.
+ int getCurrentPrimaryIndex() const;
+
+private:
+ enum UnelectableReason {
+ None = 0,
+ CannotSeeMajority = 1 << 0,
+ NotCloseEnoughToLatestOptime = 1 << 1,
+ ArbiterIAm = 1 << 2,
+ NotSecondary = 1 << 3,
+ NoPriority = 1 << 4,
+ StepDownPeriodActive = 1 << 5,
+ NoData = 1 << 6,
+ NotInitialized = 1 << 7,
+ VotedTooRecently = 1 << 8,
+ RefusesToStand = 1 << 9
};
+ typedef int UnelectableReasonMask;
+
+ // Returns the number of heartbeat pings which have occurred.
+ int _getTotalPings();
+
+ // Returns the current "ping" value for the given member by their address
+ int _getPing(const HostAndPort& host);
-} // namespace repl
-} // namespace mongo
+ // Determines if we will veto the member specified by "args.id", given that the last op
+ // we have applied locally is "lastOpApplied".
+ // If we veto, the errmsg will be filled in with a reason
+ bool _shouldVetoMember(const ReplicationCoordinator::ReplSetFreshArgs& args,
+ const Date_t& now,
+ const OpTime& lastOpApplied,
+ std::string* errmsg) const;
+
+ // Returns the index of the member with the matching id, or -1 if none match.
+ int _getMemberIndex(int id) const;
+
+ // Sees if a majority number of votes are held by members who are currently "up"
+ bool _aMajoritySeemsToBeUp() const;
+
+ // Is otherOpTime close enough (within 10 seconds) to the latest known optime to qualify
+ // for an election
+ bool _isOpTimeCloseEnoughToLatestToElect(const OpTime& otherOpTime,
+ const OpTime& ourLastOpApplied) const;
+
+ // Returns reason why "self" member is unelectable
+ UnelectableReasonMask _getMyUnelectableReason(const Date_t now,
+ const OpTime& lastOpApplied) const;
+
+ // Returns reason why memberIndex is unelectable
+ UnelectableReasonMask _getUnelectableReason(int memberIndex, const OpTime& lastOpApplied) const;
+
+ // Returns the nice text of why the node is unelectable
+ std::string _getUnelectableReasonString(UnelectableReasonMask ur) const;
+
+ // Return true if we are currently primary
+ bool _iAmPrimary() const;
+
+ // Scans through all members that are 'up' and return the latest known optime.
+ OpTime _latestKnownOpTime(const OpTime& ourLastOpApplied) const;
+
+ // Scans the electable set and returns the highest priority member index
+ int _getHighestPriorityElectableIndex(Date_t now, const OpTime& lastOpApplied) const;
+
+ // Returns true if "one" member is higher priority than "two" member
+ bool _isMemberHigherPriority(int memberOneIndex, int memberTwoIndex) const;
+
+ // Helper shortcut to self config
+ const MemberConfig& _selfConfig() const;
+
+ // Returns NULL if there is no primary, or the MemberConfig* for the current primary
+ const MemberConfig* _currentPrimaryMember() const;
+
+ /**
+ * Performs updating "_hbdata" and "_currentPrimaryIndex" for processHeartbeatResponse().
+ */
+ HeartbeatResponseAction _updateHeartbeatDataImpl(int updatedConfigIndex,
+ const MemberState& originalState,
+ Date_t now,
+ const OpTime& lastOpApplied);
+
+ /**
+ * Updates _hbdata based on the newConfig, ensuring that every member in the newConfig
+ * has an entry in _hbdata. If any nodes in the newConfig are also present in
+ * _currentConfig, copies their heartbeat info into the corresponding entry in the updated
+ * _hbdata vector.
+ */
+ void _updateHeartbeatDataForReconfig(const ReplicaSetConfig& newConfig,
+ int selfIndex,
+ Date_t now);
+
+ void _stepDownSelfAndReplaceWith(int newPrimary);
+
+ MemberState _getMyState() const;
+
+ /**
+ * Looks up the provided member in the blacklist and returns true if the member's blacklist
+ * expire time is after 'now'. If the member is found but the expire time is before 'now',
+ * the function returns false. If the member is not found in the blacklist, the function
+ * returns false.
+ **/
+ bool _memberIsBlacklisted(const MemberConfig& memberConfig, Date_t now) const;
+
+ // This node's role in the replication protocol.
+ Role _role;
+
+ // This is a unique id that is generated and set each time we transition to PRIMARY, as the
+ // result of an election.
+ OID _electionId;
+ // The time at which the current PRIMARY was elected.
+ Timestamp _electionTime;
+
+ // This node's election term. The term is used as part of the consensus algorithm to elect
+ // and maintain one primary (leader) node in the cluster.
+ long long _term = 0;
+
+ // the index of the member we currently believe is primary, if one exists, otherwise -1
+ int _currentPrimaryIndex;
+
+ // the hostandport we are currently syncing from
+ // empty if no sync source (we are primary, or we cannot connect to anyone yet)
+ HostAndPort _syncSource;
+ // These members are not chosen as sync sources for a period of time, due to connection
+ // issues with them
+ std::map<HostAndPort, Date_t> _syncSourceBlacklist;
+ // The next sync source to be chosen, requested via a replSetSyncFrom command
+ int _forceSyncSourceIndex;
+ // How far this node must fall behind before considering switching sync sources
+ Seconds _maxSyncSourceLagSecs;
+
+ // "heartbeat message"
+ // sent in requestHeartbeat respond in field "hbm"
+ std::string _hbmsg;
+ Date_t _hbmsgTime; // when it was logged
+
+ // heartbeat msg to send to others; descriptive diagnostic info
+ std::string _getHbmsg(Date_t now) const;
+
+ int _selfIndex; // this node's index in _members and _currentConfig
+
+ ReplicaSetConfig _rsConfig; // The current config, including a vector of MemberConfigs
+
+ // heartbeat data for each member. It is guaranteed that this vector will be maintained
+ // in the same order as the MemberConfigs in _currentConfig, therefore the member config
+ // index can be used to index into this vector as well.
+ std::vector<MemberHeartbeatData> _hbdata;
+
+ // Indicates that we've received a request to stepdown from PRIMARY (likely via a heartbeat)
+ bool _stepDownPending;
+
+ // Time when stepDown command expires
+ Date_t _stepDownUntil;
+
+ // A time before which this node will not stand for election.
+ Date_t _electionSleepUntil;
+
+ // The number of calls we have had to enter maintenance mode
+ int _maintenanceModeCalls;
+
+ // The sub-mode of follower that we are in. Legal values are RS_SECONDARY, RS_RECOVERING,
+ // RS_STARTUP2 (initial sync) and RS_ROLLBACK. Only meaningful if _role == Role::follower.
+ // Configured via setFollowerMode(). If the sub-mode is RS_SECONDARY, then the effective
+ // sub-mode is either RS_SECONDARY or RS_RECOVERING, depending on _maintenanceModeCalls.
+ // Rather than accesing this variable direclty, one should use the getMemberState() method,
+ // which computes the replica set node state on the fly.
+ MemberState::MS _followerMode;
+
+ typedef std::map<HostAndPort, PingStats> PingMap;
+ // Ping stats for each member by HostAndPort;
+ PingMap _pings;
+
+ // Last vote info from the election
+ struct VoteLease {
+ static const Seconds leaseTime;
+
+ Date_t when;
+ int whoId = -1;
+ HostAndPort whoHostAndPort;
+ } _voteLease;
+
+ // V1 last vote info for elections
+ LastVote _lastVote;
+};
+
+} // namespace repl
+} // namespace mongo