|
1 | 1 | 'use strict';
|
2 | 2 |
|
3 |
| -var inherits = require('util').inherits, |
| 3 | +const inherits = require('util').inherits, |
4 | 4 | f = require('util').format,
|
5 | 5 | EventEmitter = require('events').EventEmitter,
|
6 | 6 | BasicCursor = require('../cursor'),
|
7 | 7 | Logger = require('../connection/logger'),
|
8 | 8 | retrieveBSON = require('../connection/utils').retrieveBSON,
|
9 | 9 | MongoError = require('../error').MongoError,
|
| 10 | + errors = require('../error'), |
10 | 11 | Server = require('./server'),
|
11 | 12 | clone = require('./shared').clone,
|
12 | 13 | diff = require('./shared').diff,
|
13 | 14 | cloneOptions = require('./shared').cloneOptions,
|
14 | 15 | createClientInfo = require('./shared').createClientInfo,
|
15 |
| - SessionMixins = require('./shared').SessionMixins; |
| 16 | + SessionMixins = require('./shared').SessionMixins, |
| 17 | + isRetryableWritesSupported = require('./shared').isRetryableWritesSupported, |
| 18 | + txnNumber = require('./shared').txnNumber; |
16 | 19 |
|
17 |
| -var BSON = retrieveBSON(); |
| 20 | +const BSON = retrieveBSON(); |
18 | 21 |
|
19 | 22 | /**
|
20 | 23 | * @fileOverview The **Mongos** class is a class that represents a Mongos Proxy topology and is
|
@@ -879,18 +882,42 @@ Mongos.prototype.isDestroyed = function() {
|
879 | 882 |
|
880 | 883 | // Execute write operation
|
881 | 884 | var executeWriteOperation = function(self, op, ns, ops, options, callback) {
|
882 |
| - if (typeof options === 'function') { |
883 |
| - (callback = options), (options = {}), (options = options || {}); |
884 |
| - } |
885 |
| - |
886 |
| - // Ensure we have no options |
| 885 | + if (typeof options === 'function') (callback = options), (options = {}); |
887 | 886 | options = options || {};
|
| 887 | + |
888 | 888 | // Pick a server
|
889 |
| - var server = pickProxy(self); |
| 889 | + let server = pickProxy(self); |
890 | 890 | // No server found error out
|
891 | 891 | if (!server) return callback(new MongoError('no mongos proxy available'));
|
892 |
| - // Execute the command |
893 |
| - server[op](ns, ops, options, callback); |
| 892 | + |
| 893 | + if (!options.retryWrites || !options.session || !isRetryableWritesSupported(self)) { |
| 894 | + // Execute the command |
| 895 | + return server[op](ns, ops, options, callback); |
| 896 | + } |
| 897 | + |
| 898 | + // increment and assign txnNumber |
| 899 | + options.txnNumber = txnNumber(options.session); |
| 900 | + |
| 901 | + server[op](ns, ops, options, (err, result) => { |
| 902 | + if (!err) return callback(null, result); |
| 903 | + if (err instanceof errors.MongoNetworkError) { |
| 904 | + return callback(err); |
| 905 | + } |
| 906 | + |
| 907 | + // Pick another server |
| 908 | + server = pickProxy(self); |
| 909 | + |
| 910 | + // No server found error out with original error |
| 911 | + if (!server) { |
| 912 | + return callback(err); |
| 913 | + } |
| 914 | + |
| 915 | + // increment and assign txnNumber |
| 916 | + options.txnNumber = txnNumber(options.session); |
| 917 | + |
| 918 | + // rerun the operation |
| 919 | + server[op](ns, ops, options, callback); |
| 920 | + }); |
894 | 921 | };
|
895 | 922 |
|
896 | 923 | /**
|
|
0 commit comments