diff options
author | Dianna Hohensee <dianna.hohensee@10gen.com> | 2017-05-25 10:08:04 -0400 |
---|---|---|
committer | Dianna Hohensee <dianna.hohensee@10gen.com> | 2017-05-26 12:21:16 -0400 |
commit | 2f89263e637bca022ed9b8916e53637828d6f62e (patch) | |
tree | 22e372fa37dd5cac4f9cff40673b4ba2328ce85c | |
parent | 85aa900eae81fdc07d00aa4b1fb782f7ca5b4664 (diff) | |
download | mongo-2f89263e637bca022ed9b8916e53637828d6f62e.tar.gz |
SERVER-29365 make no-op applyOps wait for majority writeConcern before returning
-rw-r--r-- | src/mongo/db/commands/apply_ops.cpp | 41 |
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: |