summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJack Mulrow <jack.mulrow@mongodb.com>2018-05-18 17:34:06 -0400
committerJack Mulrow <jack.mulrow@mongodb.com>2018-06-13 11:43:45 -0400
commit8817328f87564a29e9be2ed1a746cf40e89587eb (patch)
tree1cae922e5cc0faf5b82cf914d2432e93e246ef55 /src
parent9a7b88779fd519bd955daa106d5d19244fe4072d (diff)
downloadmongo-8817328f87564a29e9be2ed1a746cf40e89587eb.tar.gz
SERVER-32064 Requests from the shell should use an implicit session by default
Diffstat (limited to 'src')
-rw-r--r--src/mongo/shell/mongo.js23
-rw-r--r--src/mongo/shell/query.js9
-rw-r--r--src/mongo/shell/session.js11
-rw-r--r--src/mongo/shell/shell_utils.cpp5
-rw-r--r--src/mongo/shell/utils.js11
5 files changed, 47 insertions, 12 deletions
diff --git a/src/mongo/shell/mongo.js b/src/mongo/shell/mongo.js
index bfb1e04f7cf..0a78e9db761 100644
--- a/src/mongo/shell/mongo.js
+++ b/src/mongo/shell/mongo.js
@@ -58,7 +58,9 @@ Mongo.prototype.getDB = function(name) {
Mongo.prototype.getDBs = function(driverSession = this._getDefaultSession()) {
var cmdObj = {listDatabases: 1};
- cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
+ if (driverSession._isExplicit || !jsTest.options().disableImplicitSessions) {
+ cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
+ }
var res = this.adminCommand(cmdObj);
if (!res.ok)
@@ -75,7 +77,9 @@ Mongo.prototype.adminCommand = function(cmd) {
*/
Mongo.prototype.getLogComponents = function(driverSession = this._getDefaultSession()) {
var cmdObj = {getParameter: 1, logComponentVerbosity: 1};
- cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
+ if (driverSession._isExplicit || !jsTest.options().disableImplicitSessions) {
+ cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
+ }
var res = this.adminCommand(cmdObj);
if (!res.ok)
@@ -106,7 +110,9 @@ Mongo.prototype.setLogLevel = function(
}
var cmdObj = {setParameter: 1, logComponentVerbosity: vDoc};
- cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
+ if (driverSession._isExplicit || !jsTest.options().disableImplicitSessions) {
+ cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
+ }
var res = this.adminCommand(cmdObj);
if (!res.ok)
@@ -426,11 +432,14 @@ Mongo.prototype.startSession = function startSession(options = {}) {
};
Mongo.prototype._getDefaultSession = function getDefaultSession() {
- // We implicitly associate a Mongo connection object with a DriverSession so that tests which
- // call DB.prototype.getMongo() and then Mongo.prototype.getDB() to get a different DB instance
- // are still causally consistent.
+ // We implicitly associate a Mongo connection object with a real session so all requests include
+ // a logical session id. These implicit sessions are intentionally not causally consistent. If
+ // implicit sessions have been globally disabled, a dummy session is used instead of a real one.
if (!this.hasOwnProperty("_defaultSession")) {
- this._defaultSession = new _DummyDriverSession(this);
+ this._defaultSession = _shouldUseImplicitSessions()
+ ? this.startSession({causalConsistency: false})
+ : new _DummyDriverSession(this);
+ this._defaultSession._isExplicit = false;
}
return this._defaultSession;
};
diff --git a/src/mongo/shell/query.js b/src/mongo/shell/query.js
index a0600845898..5ed300055a8 100644
--- a/src/mongo/shell/query.js
+++ b/src/mongo/shell/query.js
@@ -111,10 +111,11 @@ DBQuery.prototype._exec = function() {
var cmdRes = this._db.runReadCommand(findCmd, null, this._options);
this._cursor = new DBCommandCursor(this._db, cmdRes, this._batchSize);
} else {
- // Note that depending on how SERVER-32064 is implemented, we may need to alter this
- // check to account for implicit sessions, so that exhaust cursors can still be used in
- // the shell.
- if (this._db.getSession().getSessionId() !== null) {
+ // The exhaust cursor option is disallowed under a session because it doesn't work as
+ // expected, but all requests from the shell use implicit sessions, so to allow users
+ // to continue using exhaust cursors through the shell, they are only disallowed with
+ // explicit sessions.
+ if (this._db.getSession()._isExplicit) {
throw new Error("Cannot run a legacy query on a session.");
}
diff --git a/src/mongo/shell/session.js b/src/mongo/shell/session.js
index b7e77d8e9f2..07720d49047 100644
--- a/src/mongo/shell/session.js
+++ b/src/mongo/shell/session.js
@@ -209,7 +209,14 @@ var {
}
function prepareCommandRequest(driverSession, cmdObj) {
- if (serverSupports(kWireVersionSupportingLogicalSession)) {
+ if (serverSupports(kWireVersionSupportingLogicalSession) &&
+ // Always attach sessionId from explicit sessions.
+ (driverSession._isExplicit ||
+ // Check that implicit sessions are not disabled. The client must be using read
+ // commands because aggregations always use runCommand() to establish cursors but
+ // may use OP_GET_MORE (and therefore not have a session id attached) to retrieve
+ // subsequent batches.
+ (!jsTest.options().disableImplicitSessions && client.useReadCommands()))) {
cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
}
@@ -836,6 +843,8 @@ var {
this._serverSession = implMethods.createServerSession(client);
+ this._isExplicit = true;
+
this.getClient = function getClient() {
return client;
};
diff --git a/src/mongo/shell/shell_utils.cpp b/src/mongo/shell/shell_utils.cpp
index 2fedf14deec..50bd8a8ba80 100644
--- a/src/mongo/shell/shell_utils.cpp
+++ b/src/mongo/shell/shell_utils.cpp
@@ -272,6 +272,10 @@ BSONObj shouldRetryWrites(const BSONObj&, void* data) {
return BSON("" << shellGlobalParams.shouldRetryWrites);
}
+BSONObj shouldUseImplicitSessions(const BSONObj&, void* data) {
+ return BSON("" << true);
+}
+
BSONObj interpreterVersion(const BSONObj& a, void* data) {
uassert(16453, "interpreterVersion accepts no arguments", a.nFields() == 0);
return BSON("" << getGlobalScriptEngine()->getInterpreterVersionString());
@@ -310,6 +314,7 @@ void initScope(Scope& scope) {
scope.injectNative("_writeMode", writeMode);
scope.injectNative("_readMode", readMode);
scope.injectNative("_shouldRetryWrites", shouldRetryWrites);
+ scope.injectNative("_shouldUseImplicitSessions", shouldUseImplicitSessions);
scope.externalSetup();
mongo::shell_utils::installShellUtils(scope);
scope.execSetup(JSFiles::servers);
diff --git a/src/mongo/shell/utils.js b/src/mongo/shell/utils.js
index e0a765740ca..ab1c7120735 100644
--- a/src/mongo/shell/utils.js
+++ b/src/mongo/shell/utils.js
@@ -316,6 +316,7 @@ jsTestOptions = function() {
transactionLifetimeLimitSeconds: TestData.transactionLifetimeLimitSeconds,
mqlTestFile: TestData.mqlTestFile,
mqlRootPath: TestData.mqlRootPath,
+ disableImplicitSessions: TestData.disableImplicitSessions || false,
});
}
return _jsTestOptions;
@@ -561,6 +562,16 @@ if (typeof _shouldRetryWrites === 'undefined') {
};
}
+if (typeof _shouldUseImplicitSessions === 'undefined') {
+ // We ensure the _shouldUseImplicitSessions() function is always defined, in case the JavaScript
+ // engine is being used from someplace other than the mongo shell (e.g. map-reduce). If the
+ // function was not defined, implicit sessions are disabled to prevent unnecessary sessions from
+ // being created.
+ _shouldUseImplicitSessions = function _shouldUseImplicitSessions() {
+ return false;
+ };
+}
+
shellPrintHelper = function(x) {
if (typeof(x) == "undefined") {
// Make sure that we have a db var before we use it