diff options
author | Judah Schvimer <judah@mongodb.com> | 2019-04-04 11:03:50 -0400 |
---|---|---|
committer | Judah Schvimer <judah@mongodb.com> | 2019-04-04 11:03:50 -0400 |
commit | 5ab3575979e020eddf7515f21bf72eabc2cac7cd (patch) | |
tree | 5a710e11bbcf9faa36ac71935e72eba0ff115bde /src/mongo/shell/session.js | |
parent | 501b707eba794fb8fa829da6191b25b4e083667f (diff) | |
download | mongo-5ab3575979e020eddf7515f21bf72eabc2cac7cd.tar.gz |
SERVER-38937 unify txn override and auto retry on network error
Diffstat (limited to 'src/mongo/shell/session.js')
-rw-r--r-- | src/mongo/shell/session.js | 156 |
1 files changed, 77 insertions, 79 deletions
diff --git a/src/mongo/shell/session.js b/src/mongo/shell/session.js index 2b84f311b01..a8be57ae328 100644 --- a/src/mongo/shell/session.js +++ b/src/mongo/shell/session.js @@ -5,7 +5,7 @@ * https://github.com/mongodb/specifications/blob/master/source/sessions/driver-sessions.rst#abstract */ var { - DriverSession, SessionOptions, _DummyDriverSession, _DelegatingDriverSession, + DriverSession, SessionOptions, _DummyDriverSession, _DelegatingDriverSession, _ServerSession, } = (function() { "use strict"; @@ -310,7 +310,7 @@ var { if (jsTest.options().alwaysInjectTransactionNumber && serverSupports(kWireVersionSupportingRetryableWrites) && driverSession.getOptions().shouldRetryWrites() && - driverSession._serverSession.canRetryWrites(cmdObj)) { + _ServerSession.canRetryWrites(cmdObj)) { cmdObj = driverSession._serverSession.assignTransactionNumber(cmdObj); } @@ -597,83 +597,6 @@ var { return cmdObj; }; - this.canRetryWrites = function canRetryWrites(cmdObj) { - let cmdName = Object.keys(cmdObj)[0]; - - // If the command is in a wrapped form, then we look for the actual command name inside - // the query/$query object. - if (cmdName === "query" || cmdName === "$query") { - cmdObj = cmdObj[cmdName]; - cmdName = Object.keys(cmdObj)[0]; - } - - if (cmdObj.hasOwnProperty("autocommit")) { - return false; - } - - if (!isAcknowledged(cmdObj)) { - return false; - } - - if (cmdName === "insert") { - if (!Array.isArray(cmdObj.documents)) { - // The command object is malformed, so we'll just leave it as-is and let the - // server reject it. - return false; - } - - // Both single-statement operations (e.g. insertOne()) and multi-statement - // operations (e.g. insertMany()) can be retried regardless of whether they are - // executed in order by the server. - return true; - } else if (cmdName === "update") { - if (!Array.isArray(cmdObj.updates)) { - // The command object is malformed, so we'll just leave it as-is and let the - // server reject it. - return false; - } - - const hasMultiUpdate = cmdObj.updates.some(updateOp => updateOp.multi); - if (hasMultiUpdate) { - // Operations that modify multiple documents (e.g. updateMany()) cannot be - // retried. - return false; - } - - // Both single-statement operations (e.g. updateOne()) and multi-statement - // operations (e.g. bulkWrite()) can be retried regardless of whether they are - // executed in order by the server. - return true; - } else if (cmdName === "delete") { - if (!Array.isArray(cmdObj.deletes)) { - // The command object is malformed, so we'll just leave it as-is and let the - // server reject it. - return false; - } - - // We use bsonWoCompare() in order to handle cases where the limit is specified as a - // NumberInt() or NumberLong() instance. - const hasMultiDelete = cmdObj.deletes.some( - deleteOp => bsonWoCompare({_: deleteOp.limit}, {_: 0}) === 0); - if (hasMultiDelete) { - // Operations that modify multiple documents (e.g. deleteMany()) cannot be - // retried. - return false; - } - - // Both single-statement operations (e.g. deleteOne()) and multi-statement - // operations (e.g. bulkWrite()) can be retried regardless of whether they are - // executed in order by the server. - return true; - } else if (cmdName === "findAndModify" || cmdName === "findandmodify") { - // Operations that modify a single document (e.g. findOneAndUpdate()) can be - // retried. - return true; - } - - return false; - }; - this.assignTxnInfo = function assignTxnInfo(cmdObj) { // We will want to reset the transaction state to 'inactive' if a normal operation // follows a committed or aborted transaction. @@ -834,6 +757,80 @@ var { }; } + ServerSession.canRetryWrites = function canRetryWrites(cmdObj) { + let cmdName = Object.keys(cmdObj)[0]; + + // If the command is in a wrapped form, then we look for the actual command name inside the + // query/$query object. + if (cmdName === "query" || cmdName === "$query") { + cmdObj = cmdObj[cmdName]; + cmdName = Object.keys(cmdObj)[0]; + } + + if (cmdObj.hasOwnProperty("autocommit")) { + return false; + } + + if (!isAcknowledged(cmdObj)) { + return false; + } + + if (cmdName === "insert") { + if (!Array.isArray(cmdObj.documents)) { + // The command object is malformed, so we'll just leave it as-is and let the server + // reject it. + return false; + } + + // Both single-statement operations (e.g. insertOne()) and multi-statement operations + // (e.g. insertMany()) can be retried regardless of whether they are executed in order + // by the server. + return true; + } else if (cmdName === "update") { + if (!Array.isArray(cmdObj.updates)) { + // The command object is malformed, so we'll just leave it as-is and let the server + // reject it. + return false; + } + + const hasMultiUpdate = cmdObj.updates.some(updateOp => updateOp.multi); + if (hasMultiUpdate) { + // Operations that modify multiple documents (e.g. updateMany()) cannot be retried. + return false; + } + + // Both single-statement operations (e.g. updateOne()) and multi-statement operations + // (e.g. bulkWrite()) can be retried regardless of whether they are executed in order by + // the server. + return true; + } else if (cmdName === "delete") { + if (!Array.isArray(cmdObj.deletes)) { + // The command object is malformed, so we'll just leave it as-is and let the server + // reject it. + return false; + } + + // We use bsonWoCompare() in order to handle cases where the limit is specified as a + // NumberInt() or NumberLong() instance. + const hasMultiDelete = + cmdObj.deletes.some(deleteOp => bsonWoCompare({_: deleteOp.limit}, {_: 0}) === 0); + if (hasMultiDelete) { + // Operations that modify multiple documents (e.g. deleteMany()) cannot be retried. + return false; + } + + // Both single-statement operations (e.g. deleteOne()) and multi-statement operations + // (e.g. bulkWrite()) can be retried regardless of whether they are executed in order by + // the server. + return true; + } else if (cmdName === "findAndModify" || cmdName === "findandmodify") { + // Operations that modify a single document (e.g. findOneAndUpdate()) can be retried. + return true; + } + + return false; + }; + function makeDriverSessionConstructor(implMethods, defaultOptions = {}) { var driverSessionConstructor = function(client, options = defaultOptions) { const sessionAwareClient = new SessionAwareClient(client); @@ -1101,5 +1098,6 @@ var { SessionOptions: SessionOptions, _DummyDriverSession: DummyDriverSession, _DelegatingDriverSession: DelegatingDriverSession, + _ServerSession: ServerSession, }; })(); |