summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKevin Pulo <kevin.pulo@mongodb.com>2018-08-09 04:00:41 +0000
committerKevin Pulo <kevin.pulo@mongodb.com>2018-09-03 06:18:37 +0000
commit23794c14b03bb272daad7a2b25eca0b80c03a31c (patch)
tree2c60ec7adb337f99cefe1af28d8b7f4eee3c9239 /src
parent2704d7a89e64167fcff7356ada111b313146474e (diff)
downloadmongo-23794c14b03bb272daad7a2b25eca0b80c03a31c.tar.gz
SERVER-33606 fail to create logical session in shell connected to old servers
Also add --disableImplicitSessions shell cmdline arg.
Diffstat (limited to 'src')
-rw-r--r--src/mongo/shell/mongo.js26
-rw-r--r--src/mongo/shell/session.js19
-rw-r--r--src/mongo/shell/shell_options.cpp8
-rw-r--r--src/mongo/shell/shell_options.h1
-rw-r--r--src/mongo/shell/shell_utils.cpp2
5 files changed, 51 insertions, 5 deletions
diff --git a/src/mongo/shell/mongo.js b/src/mongo/shell/mongo.js
index 635c77dbc67..416416d8b3f 100644
--- a/src/mongo/shell/mongo.js
+++ b/src/mongo/shell/mongo.js
@@ -263,6 +263,10 @@ connect = function(url, user, pass) {
}
}
+ if (_shouldUseImplicitSessions()) {
+ chatty("Implicit session: " + db.getSession());
+ }
+
// Implicit sessions should not be used when opening a connection. In particular, the buildInfo
// command is erroneously marked as requiring auth in MongoDB 3.6 and therefore fails if a
// logical session id is included in the request.
@@ -445,14 +449,30 @@ Mongo.prototype._getDefaultSession = function getDefaultSession() {
// 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 = _shouldUseImplicitSessions()
- ? this.startSession({causalConsistency: false})
- : new _DummyDriverSession(this);
+ if (_shouldUseImplicitSessions()) {
+ try {
+ this._defaultSession = this.startSession({causalConsistency: false});
+ } catch (e) {
+ if (e instanceof DriverSession.UnsupportedError) {
+ chatty("WARNING: No implicit session: " + e.message);
+ this._setDummyDefaultSession();
+ } else {
+ print("ERROR: Implicit session failed: " + e.message);
+ throw(e);
+ }
+ }
+ } else {
+ this._setDummyDefaultSession();
+ }
this._defaultSession._isExplicit = false;
}
return this._defaultSession;
};
+Mongo.prototype._setDummyDefaultSession = function setDummyDefaultSession() {
+ this._defaultSession = new _DummyDriverSession(this);
+};
+
Mongo.prototype.isCausalConsistency = function isCausalConsistency() {
if (!this.hasOwnProperty("_causalConsistency")) {
this._causalConsistency = false;
diff --git a/src/mongo/shell/session.js b/src/mongo/shell/session.js
index d89be37b8e3..ce781ac0487 100644
--- a/src/mongo/shell/session.js
+++ b/src/mongo/shell/session.js
@@ -500,6 +500,10 @@ var {
let _lastUsed = new Date();
this.client = new SessionAwareClient(client);
+ if (!serverSupports(kWireVersionSupportingLogicalSession)) {
+ throw new DriverSession.UnsupportedError(
+ "Logical Sessions are only supported on server versions 3.6 and greater.");
+ }
this.handle = client._startSession();
function serverSupports(wireVersion) {
@@ -835,7 +839,7 @@ var {
};
function makeDriverSessionConstructor(implMethods, defaultOptions = {}) {
- return function(client, options = defaultOptions) {
+ var driverSessionConstructor = function(client, options = defaultOptions) {
let _options = options;
let _hasEnded = false;
@@ -964,6 +968,19 @@ var {
return this._serverSession.abortTransaction(this);
};
};
+
+ // Having a specific Error for when logical sessions aren't supported by the server, allows
+ // the correct fallback behavior in this case (while propagating other errors).
+ driverSessionConstructor.UnsupportedError = function(message) {
+ this.name = "DriverSession.UnsupportedError";
+ this.message = message;
+ this.stack = this.toString() + "\n" + (new Error()).stack;
+ };
+ driverSessionConstructor.UnsupportedError.prototype = Object.create(Error.prototype);
+ driverSessionConstructor.UnsupportedError.prototype.constructor =
+ driverSessionConstructor.UnsupportedError;
+
+ return driverSessionConstructor;
}
const DriverSession = makeDriverSessionConstructor({
diff --git a/src/mongo/shell/shell_options.cpp b/src/mongo/shell/shell_options.cpp
index 71cf4ceb147..a3e6d9e82d5 100644
--- a/src/mongo/shell/shell_options.cpp
+++ b/src/mongo/shell/shell_options.cpp
@@ -220,6 +220,11 @@ Status addMongoShellOptions(moe::OptionSection* options) {
moe::Switch,
"automatically retry write operations upon transient network errors");
+ options->addOptionChaining("disableImplicitSessions",
+ "disableImplicitSessions",
+ moe::Switch,
+ "do not automatically create and use implicit sessions");
+
options
->addOptionChaining(
"rpcProtocols", "rpcProtocols", moe::String, " none, opQueryOnly, opMsgOnly, all")
@@ -387,6 +392,9 @@ Status storeMongoShellOptions(const moe::Environment& params,
if (params.count("retryWrites")) {
shellGlobalParams.shouldRetryWrites = true;
}
+ if (params.count("disableImplicitSessions")) {
+ shellGlobalParams.shouldUseImplicitSessions = false;
+ }
if (params.count("rpcProtocols")) {
std::string protos = params["rpcProtocols"].as<string>();
auto parsedRPCProtos = rpc::parseProtocolSet(protos);
diff --git a/src/mongo/shell/shell_options.h b/src/mongo/shell/shell_options.h
index 28766921807..c0a66fb35e2 100644
--- a/src/mongo/shell/shell_options.h
+++ b/src/mongo/shell/shell_options.h
@@ -73,6 +73,7 @@ struct ShellGlobalParams {
std::string writeMode = "commands";
std::string readMode = "compatibility";
bool shouldRetryWrites = false;
+ bool shouldUseImplicitSessions = true;
boost::optional<rpc::ProtocolSet> rpcProtocols = boost::none;
diff --git a/src/mongo/shell/shell_utils.cpp b/src/mongo/shell/shell_utils.cpp
index cac50ff9de9..cfb15de8f41 100644
--- a/src/mongo/shell/shell_utils.cpp
+++ b/src/mongo/shell/shell_utils.cpp
@@ -284,7 +284,7 @@ BSONObj shouldRetryWrites(const BSONObj&, void* data) {
}
BSONObj shouldUseImplicitSessions(const BSONObj&, void* data) {
- return BSON("" << true);
+ return BSON("" << shellGlobalParams.shouldUseImplicitSessions);
}
BSONObj interpreterVersion(const BSONObj& a, void* data) {