summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndy Schwerin <Andy Schwerin schwerin@mongodb.com>2017-04-27 09:58:05 -0400
committerAndy Schwerin <Andy Schwerin schwerin@mongodb.com>2017-04-27 09:58:05 -0400
commit2ee2c54bd64b5981c2e6c421475c69139a85c1db (patch)
tree9e2f121af9929fbd0d79872a7d34ea4663eea095 /src
parentc87222f209ac73621274869cc459672cc3ff978c (diff)
downloadmongo-2ee2c54bd64b5981c2e6c421475c69139a85c1db.tar.gz
SERVER-28865 Replace ReplicationExecutor's prng in ReplicationCoordinatorImpl with an explicit prng.
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp12
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.h11
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_elect.cpp4
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp9
4 files changed, 25 insertions, 11 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index 64888f7fa89..e538718650c 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -320,7 +320,8 @@ ReplicationCoordinatorImpl::ReplicationCoordinatorImpl(
_sleptLastElection(false),
_canAcceptNonLocalWrites(!(settings.usingReplSets() || settings.isSlave())),
_canServeNonLocalReads(0U),
- _storage(storage) {
+ _storage(storage),
+ _random(prngSeed) {
invariant(_service);
@@ -336,7 +337,7 @@ ReplicationCoordinatorImpl::ReplicationCoordinatorImpl(
_externalState->setupNoopWriter(kNoopWriterPeriod);
}
-ReplicationCoordinatorImpl::~ReplicationCoordinatorImpl() {}
+ReplicationCoordinatorImpl::~ReplicationCoordinatorImpl() = default;
void ReplicationCoordinatorImpl::waitForStartUpComplete_forTest() {
_waitForStartUpComplete();
@@ -370,7 +371,8 @@ Date_t ReplicationCoordinatorImpl::getElectionTimeout_forTest() const {
}
Milliseconds ReplicationCoordinatorImpl::getRandomizedElectionOffset_forTest() {
- return _getRandomizedElectionOffset();
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ return _getRandomizedElectionOffset_inlock();
}
boost::optional<Date_t> ReplicationCoordinatorImpl::getPriorityTakeover_forTest() const {
@@ -3786,5 +3788,9 @@ ReplicationCoordinatorImpl::_cancelElectionIfNeeded_inTopoLock() {
return _electionFinishedEvent;
}
+int64_t ReplicationCoordinatorImpl::_nextRandomInt64_inlock(int64_t limit) {
+ return _random.nextInt64(limit);
+}
+
} // namespace repl
} // namespace mongo
diff --git a/src/mongo/db/repl/replication_coordinator_impl.h b/src/mongo/db/repl/replication_coordinator_impl.h
index fd37c6a7a47..04c22e2e829 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.h
+++ b/src/mongo/db/repl/replication_coordinator_impl.h
@@ -49,6 +49,7 @@
#include "mongo/db/storage/snapshot_name.h"
#include "mongo/executor/task_executor.h"
#include "mongo/platform/atomic_word.h"
+#include "mongo/platform/random.h"
#include "mongo/platform/unordered_map.h"
#include "mongo/platform/unordered_set.h"
#include "mongo/stdx/condition_variable.h"
@@ -808,7 +809,7 @@ private:
* Return a randomized offset amount that is scaled in proportion to the size of the
* _electionTimeoutPeriod. Used to add randomization to an election timeout.
*/
- Milliseconds _getRandomizedElectionOffset();
+ Milliseconds _getRandomizedElectionOffset_inlock();
/**
* Helper for _handleHeartbeatResponse.
@@ -1233,6 +1234,11 @@ private:
*/
Status _waitUntilClusterTimeForRead(OperationContext* opCtx, LogicalTime clusterTime);
+ /**
+ * Returns a pseudorandom number no less than 0 and less than limit (which must be positive).
+ */
+ int64_t _nextRandomInt64_inlock(int64_t limit);
+
//
// All member variables are labeled with one of the following codes indicating the
// synchronization rules for accessing them.
@@ -1430,6 +1436,9 @@ private:
// Cached copy of the current config protocol version.
AtomicInt64 _protVersion; // (S)
+ // Source of random numbers used in setting election timeouts, etc.
+ PseudoRandom _random; // (M)
+
// This setting affects the Applier prefetcher behavior.
mutable stdx::mutex _indexPrefetchMutex;
ReplSettings::IndexPrefetchConfig _indexPrefetchConfig =
diff --git a/src/mongo/db/repl/replication_coordinator_impl_elect.cpp b/src/mongo/db/repl/replication_coordinator_impl_elect.cpp
index a1074150b03..be7d6ea79d7 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_elect.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_elect.cpp
@@ -173,7 +173,7 @@ void ReplicationCoordinatorImpl::_onFreshnessCheckComplete() {
break;
case FreshnessChecker::FreshnessTie:
if ((_selfIndex != 0) && !_sleptLastElection) {
- const auto ms = Milliseconds(_replExecutor->nextRandomInt64(1000) + 50);
+ const auto ms = Milliseconds(_nextRandomInt64_inlock(1000) + 50);
const Date_t nextCandidateTime = now + ms;
log() << "possible election tie; sleeping " << ms << " until "
<< dateToISOStringLocal(nextCandidateTime);
@@ -245,7 +245,7 @@ void ReplicationCoordinatorImpl::_onElectCmdRunnerComplete() {
<< " votes, but needed at least " << _rsConfig.getMajorityVoteCount();
// Suppress ourselves from standing for election again, giving other nodes a chance
// to win their elections.
- const auto ms = Milliseconds(_replExecutor->nextRandomInt64(1000) + 50);
+ const auto ms = Milliseconds(_nextRandomInt64_inlock(1000) + 50);
const Date_t now(_replExecutor->now());
const Date_t nextCandidateTime = now + ms;
log() << "waiting until " << nextCandidateTime << " before standing for election again";
diff --git a/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp b/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp
index 68e1a61c4ac..99b39be285f 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp
@@ -69,7 +69,7 @@ MONGO_FP_DECLARE(blockHeartbeatReconfigFinish);
using executor::RemoteCommandRequest;
-Milliseconds ReplicationCoordinatorImpl::_getRandomizedElectionOffset() {
+Milliseconds ReplicationCoordinatorImpl::_getRandomizedElectionOffset_inlock() {
long long electionTimeout = durationCount<Milliseconds>(_rsConfig.getElectionTimeoutPeriod());
long long randomOffsetUpperBound =
electionTimeout * _externalState->getElectionTimeoutOffsetLimitFraction();
@@ -79,8 +79,7 @@ Milliseconds ReplicationCoordinatorImpl::_getRandomizedElectionOffset() {
return Milliseconds(0);
}
- int64_t randomOffset = _replExecutor->nextRandomInt64(randomOffsetUpperBound);
- return Milliseconds(randomOffset);
+ return Milliseconds{_nextRandomInt64_inlock(randomOffsetUpperBound)};
}
void ReplicationCoordinatorImpl::_doMemberHeartbeat(executor::TaskExecutor::CallbackArgs cbData,
@@ -302,7 +301,7 @@ stdx::unique_lock<stdx::mutex> ReplicationCoordinatorImpl::_handleHeartbeatRespo
// Add randomized offset to calculated priority takeover delay.
Milliseconds priorityTakeoverDelay = _rsConfig.getPriorityTakeoverDelay(_selfIndex);
- Milliseconds randomOffset = _getRandomizedElectionOffset();
+ Milliseconds randomOffset = _getRandomizedElectionOffset_inlock();
_priorityTakeoverWhen = _replExecutor->now() + priorityTakeoverDelay + randomOffset;
log() << "Scheduling priority takeover at " << _priorityTakeoverWhen;
_priorityTakeoverCbh = _scheduleWorkAt(
@@ -827,7 +826,7 @@ void ReplicationCoordinatorImpl::_cancelAndRescheduleElectionTimeout_inlock() {
return;
}
- Milliseconds randomOffset = _getRandomizedElectionOffset();
+ Milliseconds randomOffset = _getRandomizedElectionOffset_inlock();
auto now = _replExecutor->now();
auto when = now + _rsConfig.getElectionTimeoutPeriod() + randomOffset;
invariant(when > now);