summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/mmap_v1/dur_big_atomic_update.js13
-rw-r--r--src/mongo/db/dbdirectclient.cpp17
-rw-r--r--src/mongo/db/dbdirectclient.h2
-rw-r--r--src/mongo/db/lasterror.cpp7
-rw-r--r--src/mongo/db/lasterror.h9
-rw-r--r--src/mongo/db/service_entry_point_mongod.cpp2
-rw-r--r--src/mongo/s/service_entry_point_mongos.cpp2
7 files changed, 25 insertions, 27 deletions
diff --git a/jstests/mmap_v1/dur_big_atomic_update.js b/jstests/mmap_v1/dur_big_atomic_update.js
index 41c85adf80a..567349ed72b 100644
--- a/jstests/mmap_v1/dur_big_atomic_update.js
+++ b/jstests/mmap_v1/dur_big_atomic_update.js
@@ -33,15 +33,14 @@ for (var i = 0; i < 1024; i++) {
assert.writeOK(bulk.execute());
// Do it again but in a db.eval
-d.eval(function(big_string) {
- new Mongo().getDB("test").foo.update(
- {}, {$set: {big_string: big_string}}, false, /*multi*/ true);
+var err = d.eval(function(big_string) {
+ var db = new Mongo().getDB("test");
+ db.foo.update({}, {$set: {big_string: big_string}}, false, /*multi*/ true);
+ return db.getLastErrorObj();
}, big_string); // Can't pass in connection or DB objects
-err = d.getLastErrorObj();
-
-assert(err.err == null);
-assert(err.n == 1024);
+assert.eq(err.err, null, tojson(err));
+assert.eq(err.n, 1024, tojson(err));
// free up space
d.dropDatabase();
diff --git a/src/mongo/db/dbdirectclient.cpp b/src/mongo/db/dbdirectclient.cpp
index b6df5ab4dd3..76f389b8434 100644
--- a/src/mongo/db/dbdirectclient.cpp
+++ b/src/mongo/db/dbdirectclient.cpp
@@ -32,15 +32,17 @@
#include "mongo/db/dbdirectclient.h"
+#include <boost/core/swap.hpp>
+
#include "mongo/db/client.h"
#include "mongo/db/commands.h"
#include "mongo/db/curop.h"
-#include "mongo/db/lasterror.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/wire_version.h"
#include "mongo/rpc/get_status_from_command_result.h"
#include "mongo/transport/service_entry_point.h"
#include "mongo/util/log.h"
+#include "mongo/util/scopeguard.h"
namespace mongo {
@@ -122,9 +124,14 @@ QueryOptions DBDirectClient::_lookupAvailableOptions() {
}
namespace {
-DbResponse loopbackBuildResponse(OperationContext* const opCtx, Message& toSend) {
+DbResponse loopbackBuildResponse(OperationContext* const opCtx,
+ LastError* lastError,
+ Message& toSend) {
DirectClientScope directClientScope(opCtx);
- LastError::get(opCtx->getClient()).startDirectClientRequest();
+ boost::swap(*lastError, LastError::get(opCtx->getClient()));
+ ON_BLOCK_EXIT([&] { boost::swap(*lastError, LastError::get(opCtx->getClient())); });
+
+ LastError::get(opCtx->getClient()).startRequest();
CurOp curOp(opCtx);
toSend.header().setId(nextMessageId());
@@ -134,7 +141,7 @@ DbResponse loopbackBuildResponse(OperationContext* const opCtx, Message& toSend)
} // namespace
bool DBDirectClient::call(Message& toSend, Message& response, bool assertOk, string* actualServer) {
- auto dbResponse = loopbackBuildResponse(_opCtx, toSend);
+ auto dbResponse = loopbackBuildResponse(_opCtx, &_lastError, toSend);
invariant(!dbResponse.response.empty());
response = std::move(dbResponse.response);
@@ -142,7 +149,7 @@ bool DBDirectClient::call(Message& toSend, Message& response, bool assertOk, str
}
void DBDirectClient::say(Message& toSend, bool isRetry, string* actualServer) {
- auto dbResponse = loopbackBuildResponse(_opCtx, toSend);
+ auto dbResponse = loopbackBuildResponse(_opCtx, &_lastError, toSend);
invariant(dbResponse.response.empty());
}
diff --git a/src/mongo/db/dbdirectclient.h b/src/mongo/db/dbdirectclient.h
index c5d4bc78f6f..4432d775e23 100644
--- a/src/mongo/db/dbdirectclient.h
+++ b/src/mongo/db/dbdirectclient.h
@@ -30,6 +30,7 @@
#include "mongo/client/dbclientinterface.h"
#include "mongo/db/dbmessage.h"
+#include "mongo/db/lasterror.h"
#include "mongo/util/net/hostandport.h"
namespace mongo {
@@ -102,6 +103,7 @@ public:
private:
OperationContext* _opCtx;
+ LastError _lastError; // This LastError will be used for all operations on this client.
};
} // namespace mongo
diff --git a/src/mongo/db/lasterror.cpp b/src/mongo/db/lasterror.cpp
index 2521fa99466..c9d9aca453e 100644
--- a/src/mongo/db/lasterror.cpp
+++ b/src/mongo/db/lasterror.cpp
@@ -110,15 +110,10 @@ void LastError::disable() {
_nPrev--; // caller is a command that shouldn't count as an operation
}
-void LastError::startTopLevelRequest() {
+void LastError::startRequest() {
_disabled = false;
++_nPrev;
_hadNotMasterError = false;
}
-void LastError::startDirectClientRequest() {
- _disabled = false;
- ++_nPrev;
-}
-
} // namespace mongo
diff --git a/src/mongo/db/lasterror.h b/src/mongo/db/lasterror.h
index ee450089595..8c5a5d3bfb3 100644
--- a/src/mongo/db/lasterror.h
+++ b/src/mongo/db/lasterror.h
@@ -50,14 +50,9 @@ public:
void reset(bool valid = false);
/**
- * when db receives a top level message/request, call this
+ * when db receives a message/request, call this
*/
- void startTopLevelRequest();
-
- /**
- * when DBDirectClient receives a message/request, call this
- */
- void startDirectClientRequest();
+ void startRequest();
/**
* Disables error recording for the current operation.
diff --git a/src/mongo/db/service_entry_point_mongod.cpp b/src/mongo/db/service_entry_point_mongod.cpp
index f8ddfda6ec3..37b3d4e51fc 100644
--- a/src/mongo/db/service_entry_point_mongod.cpp
+++ b/src/mongo/db/service_entry_point_mongod.cpp
@@ -1039,7 +1039,7 @@ DbResponse ServiceEntryPointMongod::handleRequest(OperationContext* opCtx, const
if (c.isInDirectClient()) {
invariant(!opCtx->lockState()->inAWriteUnitOfWork());
} else {
- LastError::get(c).startTopLevelRequest();
+ LastError::get(c).startRequest();
AuthorizationSession::get(c)->startRequest(opCtx);
// We should not be holding any locks at this point
diff --git a/src/mongo/s/service_entry_point_mongos.cpp b/src/mongo/s/service_entry_point_mongos.cpp
index 709485758b0..dc1f8312b97 100644
--- a/src/mongo/s/service_entry_point_mongos.cpp
+++ b/src/mongo/s/service_entry_point_mongos.cpp
@@ -81,7 +81,7 @@ DbResponse ServiceEntryPointMongos::handleRequest(OperationContext* opCtx, const
ClusterLastErrorInfo::get(client) = std::make_shared<ClusterLastErrorInfo>();
}
ClusterLastErrorInfo::get(client)->newRequest();
- LastError::get(client).startTopLevelRequest();
+ LastError::get(client).startRequest();
AuthorizationSession::get(opCtx->getClient())->startRequest(opCtx);
DbMessage dbm(message);