summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Russotto <matthew.russotto@mongodb.com>2020-10-19 11:29:31 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-10-21 23:07:48 +0000
commitd81c2c914b3c3be9079af9c522060755df4ef946 (patch)
treea0b4289cee8e68efa8051ca703e86287ad0e25be
parentcbb066534c68f7581fdc9b115fb46ae588b91656 (diff)
downloadmongo-d81c2c914b3c3be9079af9c522060755df4ef946.tar.gz
SERVER-51726 Maintain status code compatibility when main executor is shut down
-rw-r--r--src/mongo/db/repl/initial_syncer.cpp11
-rw-r--r--src/mongo/db/repl/initial_syncer.h6
2 files changed, 12 insertions, 5 deletions
diff --git a/src/mongo/db/repl/initial_syncer.cpp b/src/mongo/db/repl/initial_syncer.cpp
index be43928e9b1..11b1d0dada1 100644
--- a/src/mongo/db/repl/initial_syncer.cpp
+++ b/src/mongo/db/repl/initial_syncer.cpp
@@ -1676,7 +1676,7 @@ void InitialSyncer::_finishInitialSyncAttempt(const StatusWith<OpTimeAndWallTime
"Unable to schedule initial syncer completion task. Running callback on "
"current thread",
"error"_attr = redact(scheduleResult.getStatus()));
- _finishCallback(result);
+ _finishCallback(result, scheduleResult.getStatus());
}
});
@@ -1772,7 +1772,8 @@ void InitialSyncer::_finishInitialSyncAttempt(const StatusWith<OpTimeAndWallTime
finishCallbackGuard.dismiss();
}
-void InitialSyncer::_finishCallback(StatusWith<OpTimeAndWallTime> lastApplied) {
+void InitialSyncer::_finishCallback(StatusWith<OpTimeAndWallTime> lastApplied,
+ Status schedulingError) {
// After running callback function, clear '_onCompletion' to release any resources that might be
// held by this function object.
// '_onCompletion' must be moved to a temporary copy and destroyed outside the lock in case
@@ -1803,8 +1804,10 @@ void InitialSyncer::_finishCallback(StatusWith<OpTimeAndWallTime> lastApplied) {
_retryingOperation = boost::none;
// Canceling an attempt sometimes results in a ShutdownInProgress code, which callers don't
- // expect. Convert that to CallbackCanceled.
- if (!lastApplied.isOK() && lastApplied.getStatus().code() == ErrorCodes::ShutdownInProgress) {
+ // expect. Convert that to CallbackCanceled. If the main executor isn't running, we skip
+ // this, because callers expect ShutdownInProgress in that case.
+ if (schedulingError.isOK() && !lastApplied.isOK() &&
+ lastApplied.getStatus().code() == ErrorCodes::ShutdownInProgress) {
lastApplied = Status(ErrorCodes::CallbackCanceled, lastApplied.getStatus().reason());
}
// Completion callback must be invoked outside mutex.
diff --git a/src/mongo/db/repl/initial_syncer.h b/src/mongo/db/repl/initial_syncer.h
index 6ec9b2d495d..6f3d8adc6a3 100644
--- a/src/mongo/db/repl/initial_syncer.h
+++ b/src/mongo/db/repl/initial_syncer.h
@@ -585,8 +585,12 @@ private:
/**
* Invokes completion callback and transitions state to State::kComplete.
+ *
+ * schedulingError is non-OK if the _finishCallback could not be scheduled and
+ * is running in-line.
*/
- void _finishCallback(StatusWith<OpTimeAndWallTime> lastApplied);
+ void _finishCallback(StatusWith<OpTimeAndWallTime> lastApplied,
+ Status schedulingError = Status::OK());
// Obtains a valid sync source from the sync source selector.
// Returns error if a sync source cannot be found.