summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDianna Hohensee <dianna.hohensee@10gen.com>2017-05-25 10:08:04 -0400
committerDianna Hohensee <dianna.hohensee@10gen.com>2017-05-26 12:21:16 -0400
commit2f89263e637bca022ed9b8916e53637828d6f62e (patch)
tree22e372fa37dd5cac4f9cff40673b4ba2328ce85c
parent85aa900eae81fdc07d00aa4b1fb782f7ca5b4664 (diff)
downloadmongo-2f89263e637bca022ed9b8916e53637828d6f62e.tar.gz
SERVER-29365 make no-op applyOps wait for majority writeConcern before returning
-rw-r--r--src/mongo/db/commands/apply_ops.cpp41
1 files changed, 25 insertions, 16 deletions
diff --git a/src/mongo/db/commands/apply_ops.cpp b/src/mongo/db/commands/apply_ops.cpp
index f4f0b930a8c..77e89db3aca 100644
--- a/src/mongo/db/commands/apply_ops.cpp
+++ b/src/mongo/db/commands/apply_ops.cpp
@@ -121,22 +121,31 @@ public:
txn->setWriteConcern(wcResult.getValue());
setupSynchronousCommit(txn);
+ auto applyOpsRes = [&]() {
+ try {
+ // Note: this scope guard must go out of scope before the waitForWriteConcern below!
+ auto client = txn->getClient();
+ auto lastOpAtOperationStart = repl::ReplClientInfo::forClient(client).getLastOp();
+ ScopeGuard lastOpSetterGuard =
+ MakeObjGuard(repl::ReplClientInfo::forClient(client),
+ &repl::ReplClientInfo::setLastOpToSystemLastOpTime,
+ txn);
+
+ auto res = appendCommandStatus(result, applyOps(txn, dbname, cmdObj, &result));
+
+ if (repl::ReplClientInfo::forClient(client).getLastOp() != lastOpAtOperationStart) {
+ // If this operation has already generated a new lastOp, don't bother setting it
+ // here. No-op applyOps will not generate a new lastOp, so we still need the
+ // guard to fire in that case.
+ lastOpSetterGuard.Dismiss();
+ }
- auto client = txn->getClient();
- auto lastOpAtOperationStart = repl::ReplClientInfo::forClient(client).getLastOp();
- ScopeGuard lastOpSetterGuard =
- MakeObjGuard(repl::ReplClientInfo::forClient(client),
- &repl::ReplClientInfo::setLastOpToSystemLastOpTime,
- txn);
-
- auto applyOpsStatus = appendCommandStatus(result, applyOps(txn, dbname, cmdObj, &result));
-
- if (repl::ReplClientInfo::forClient(client).getLastOp() != lastOpAtOperationStart) {
- // If this operation has already generated a new lastOp, don't bother setting it
- // here. No-op applyOps will not generate a new lastOp, so we still need the guard to
- // fire in that case.
- lastOpSetterGuard.Dismiss();
- }
+ return res;
+ } catch (const DBException& e) {
+ appendCommandStatus(result, e.toStatus());
+ return false;
+ }
+ }();
WriteConcernResult res;
auto waitForWCStatus =
@@ -146,7 +155,7 @@ public:
&res);
appendCommandWCStatus(result, waitForWCStatus);
- return applyOpsStatus;
+ return applyOpsRes;
}
private: