summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2020-10-16 13:56:28 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-10-16 18:14:20 +0000
commitb179b1b261591857523ee332d220842615b9c8c6 (patch)
treeaac3a28cca0db2b6eeebcc1bd0ef08c3385b5bc4
parentaf298544ba207890ef3dc9da9b5b7db8e17eb2bb (diff)
downloadmongo-b179b1b261591857523ee332d220842615b9c8c6.tar.gz
SERVER-46995 add methods for synchronizing IndexBuildAction to ReplIndexBuildState
-rw-r--r--src/mongo/db/index_builds_coordinator_mongod.cpp29
-rw-r--r--src/mongo/db/repl_index_build_state.cpp20
-rw-r--r--src/mongo/db/repl_index_build_state.h18
3 files changed, 46 insertions, 21 deletions
diff --git a/src/mongo/db/index_builds_coordinator_mongod.cpp b/src/mongo/db/index_builds_coordinator_mongod.cpp
index 5d75034fe7f..eef382c66de 100644
--- a/src/mongo/db/index_builds_coordinator_mongod.cpp
+++ b/src/mongo/db/index_builds_coordinator_mongod.cpp
@@ -522,10 +522,7 @@ void IndexBuildsCoordinatorMongod::_signalPrimaryForCommitReadiness(
replState->clearVoteRequestCbk();
};
- auto needToVote = [replState]() -> bool {
- stdx::unique_lock<Latch> lk(replState->mutex);
- return !replState->waitForNextAction->getFuture().isReady() ? true : false;
- };
+ auto needToVote = [replState]() -> bool { return !replState->getNextActionNoWait(); };
// Retry 'voteCommitIndexBuild' command on error until we have been signaled either with commit
// or abort. This way, we can make sure majority of nodes will never stop voting and wait for
@@ -590,11 +587,7 @@ void IndexBuildsCoordinatorMongod::_signalPrimaryForCommitReadiness(
IndexBuildAction IndexBuildsCoordinatorMongod::_drainSideWritesUntilNextActionIsAvailable(
OperationContext* opCtx, std::shared_ptr<ReplIndexBuildState> replState) {
- auto future = [&] {
- stdx::unique_lock<Latch> lk(replState->mutex);
- invariant(replState->waitForNextAction);
- return replState->waitForNextAction->getFuture();
- }();
+ auto future = replState->getNextActionFuture();
// Waits until the promise is fulfilled or the deadline expires.
IndexBuildAction nextAction;
@@ -696,11 +689,7 @@ void IndexBuildsCoordinatorMongod::_waitForNextIndexBuildActionAndCommit(
"No longer primary while attempting to commit. Waiting again for next action "
"before completing final phase",
"buildUUID"_attr = replState->buildUUID);
- {
- stdx::unique_lock<Latch> lk(replState->mutex);
- replState->waitForNextAction =
- std::make_unique<SharedPromise<IndexBuildAction>>();
- }
+ replState->resetNextActionPromise();
needsToRetryWait = true;
break;
case CommitResult::kLockTimeout:
@@ -802,11 +791,11 @@ Status IndexBuildsCoordinatorMongod::setCommitQuorum(OperationContext* opCtx,
// satisfied with the stale read commit quorum value.
Lock::ExclusiveLock commitQuorumLk(opCtx->lockState(), replState->commitQuorumLock.get());
{
- stdx::unique_lock<Latch> lk(replState->mutex);
- if (replState->waitForNextAction->getFuture().isReady()) {
+ if (auto action = replState->getNextActionNoWait()) {
return Status(ErrorCodes::CommandFailed,
str::stream() << "Commit quorum can't be changed as index build is "
- "ready to commit or abort");
+ "ready to commit or abort: "
+ << indexBuildActionToString(*action));
}
}
@@ -817,10 +806,8 @@ Status IndexBuildsCoordinatorMongod::setCommitQuorum(OperationContext* opCtx,
{
// Check to see the index build hasn't received commit index build signal while updating
// the commit quorum value on-disk.
- stdx::unique_lock<Latch> lk(replState->mutex);
- if (replState->waitForNextAction->getFuture().isReady()) {
- auto action = replState->waitForNextAction->getFuture().get();
- invariant(action != IndexBuildAction::kCommitQuorumSatisfied);
+ if (auto action = replState->getNextActionNoWait()) {
+ invariant(*action != IndexBuildAction::kCommitQuorumSatisfied);
}
}
return status;
diff --git a/src/mongo/db/repl_index_build_state.cpp b/src/mongo/db/repl_index_build_state.cpp
index a05adeb21e8..1bcf3786ec5 100644
--- a/src/mongo/db/repl_index_build_state.cpp
+++ b/src/mongo/db/repl_index_build_state.cpp
@@ -359,6 +359,26 @@ void ReplIndexBuildState::clearVoteRequestCbk() {
voteCmdCbkHandle = executor::TaskExecutor::CallbackHandle();
}
+void ReplIndexBuildState::resetNextActionPromise() {
+ stdx::unique_lock<Latch> lk(mutex);
+ waitForNextAction = std::make_unique<SharedPromise<IndexBuildAction>>();
+}
+
+SharedSemiFuture<IndexBuildAction> ReplIndexBuildState::getNextActionFuture() const {
+ stdx::unique_lock<Latch> lk(mutex);
+ invariant(waitForNextAction, str::stream() << buildUUID);
+ return waitForNextAction->getFuture();
+}
+
+boost::optional<IndexBuildAction> ReplIndexBuildState::getNextActionNoWait() const {
+ stdx::unique_lock<Latch> lk(mutex);
+ auto future = waitForNextAction->getFuture();
+ if (!future.isReady()) {
+ return boost::none;
+ }
+ return future.get();
+}
+
bool ReplIndexBuildState::isResumable() const {
stdx::unique_lock<Latch> lk(mutex);
return !_lastOpTimeBeforeInterceptors.isNull();
diff --git a/src/mongo/db/repl_index_build_state.h b/src/mongo/db/repl_index_build_state.h
index d2b4a7918bc..6777b1078fd 100644
--- a/src/mongo/db/repl_index_build_state.h
+++ b/src/mongo/db/repl_index_build_state.h
@@ -325,6 +325,24 @@ public:
void clearVoteRequestCbk();
/**
+ * (Re-)initializes promise for next action.
+ */
+ void resetNextActionPromise();
+
+
+ /**
+ * Returns a future that can be used to wait on 'waitForNextAction' for the next action to be
+ * available.
+ */
+ SharedSemiFuture<IndexBuildAction> getNextActionFuture() const;
+
+ /**
+ * Gets next action from future if available.
+ * Returns boost::none if future is not ready.
+ */
+ boost::optional<IndexBuildAction> getNextActionNoWait() const;
+
+ /**
* Accessor and mutator for last optime in the oplog before the interceptors were installed.
* This supports resumable index builds.
*/