summaryrefslogtreecommitdiff
path: root/src/mongo/db/commands/dbcommands.cpp
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@mongodb.com>2017-04-19 17:24:51 -0400
committerSpencer T Brody <spencer@mongodb.com>2017-04-20 16:04:38 -0400
commit5bdd2f49c02e5fe2812ccc6f21502799fa5a3268 (patch)
treeb3f6039c707fac3d598eb582da4067cae0275f66 /src/mongo/db/commands/dbcommands.cpp
parent7e6025227bfbf41d6ac1ad90ef985dcb7afe668f (diff)
downloadmongo-5bdd2f49c02e5fe2812ccc6f21502799fa5a3268.tar.gz
SERVER-25765 Commands should wait for write concern even if they throw an exception
Diffstat (limited to 'src/mongo/db/commands/dbcommands.cpp')
-rw-r--r--src/mongo/db/commands/dbcommands.cpp41
1 files changed, 24 insertions, 17 deletions
diff --git a/src/mongo/db/commands/dbcommands.cpp b/src/mongo/db/commands/dbcommands.cpp
index 4dbae9567da..aefee2bb4df 100644
--- a/src/mongo/db/commands/dbcommands.cpp
+++ b/src/mongo/db/commands/dbcommands.cpp
@@ -1370,6 +1370,27 @@ StatusWith<repl::ReadConcernArgs> _extractReadConcern(const BSONObj& cmdObj,
return readConcernArgs;
}
+void _waitForWriteConcernAndAddToCommandResponse(OperationContext* opCtx,
+ const std::string& commandName,
+ BSONObjBuilder* commandResponseBuilder) {
+ WriteConcernResult res;
+ auto waitForWCStatus =
+ waitForWriteConcern(opCtx,
+ repl::ReplClientInfo::forClient(opCtx->getClient()).getLastOp(),
+ opCtx->getWriteConcern(),
+ &res);
+ Command::appendCommandWCStatus(*commandResponseBuilder, waitForWCStatus, res);
+
+ // SERVER-22421: This code is to ensure error response backwards compatibility with the
+ // user management commands. This can be removed in 3.6.
+ if (!waitForWCStatus.isOK() && Command::isUserManagementCommand(commandName)) {
+ BSONObj temp = commandResponseBuilder->asTempObj().copy();
+ commandResponseBuilder->resetToEmpty();
+ Command::appendCommandStatus(*commandResponseBuilder, waitForWCStatus);
+ commandResponseBuilder->appendElementsUnique(temp);
+ }
+}
+
} // namespace
// This really belongs in commands.cpp, but we need to move it here so we can
@@ -1449,29 +1470,15 @@ bool Command::run(OperationContext* opCtx,
const auto oldWC = opCtx->getWriteConcern();
ON_BLOCK_EXIT([&] { opCtx->setWriteConcern(oldWC); });
opCtx->setWriteConcern(wcResult.getValue());
+ ON_BLOCK_EXIT([&] {
+ _waitForWriteConcernAndAddToCommandResponse(opCtx, getName(), &inPlaceReplyBob);
+ });
result = run(opCtx, db, cmd, errmsg, inPlaceReplyBob);
// Nothing in run() should change the writeConcern.
dassert(SimpleBSONObjComparator::kInstance.evaluate(opCtx->getWriteConcern().toBSON() ==
wcResult.getValue().toBSON()));
-
- WriteConcernResult res;
- auto waitForWCStatus =
- waitForWriteConcern(opCtx,
- repl::ReplClientInfo::forClient(opCtx->getClient()).getLastOp(),
- wcResult.getValue(),
- &res);
- appendCommandWCStatus(inPlaceReplyBob, waitForWCStatus, res);
-
- // SERVER-22421: This code is to ensure error response backwards compatibility with the
- // user management commands. This can be removed in 3.6.
- if (!waitForWCStatus.isOK() && isUserManagementCommand(getName())) {
- BSONObj temp = inPlaceReplyBob.asTempObj().copy();
- inPlaceReplyBob.resetToEmpty();
- appendCommandStatus(inPlaceReplyBob, waitForWCStatus);
- inPlaceReplyBob.appendElementsUnique(temp);
- }
}
// When a linearizable read command is passed in, check to make sure we're reading