-
Notifications
You must be signed in to change notification settings - Fork 1.8k
NODE-2579/3.6/global-promise-prereq #2340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
158c141
32eb671
9960092
d3e8428
a6bc216
75278d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
'use strict'; | ||
|
||
const PromiseProvider = require('./promise_provider'); | ||
const applyWriteConcern = require('./utils').applyWriteConcern; | ||
|
||
const AddUserOperation = require('./operations/add_user'); | ||
const ExecuteDbAdminCommandOperation = require('./operations/execute_db_admin_command'); | ||
const RemoveUserOperation = require('./operations/remove_user'); | ||
|
@@ -42,14 +42,14 @@ const executeOperation = require('./operations/execute_operation'); | |
* @class | ||
* @return {Admin} a collection instance. | ||
*/ | ||
function Admin(db, topology, promiseLibrary) { | ||
function Admin(db, topology) { | ||
if (!(this instanceof Admin)) return new Admin(db, topology); | ||
|
||
// Internal state | ||
this.s = { | ||
db: db, | ||
topology: topology, | ||
promiseLibrary: promiseLibrary | ||
promiseLibrary: PromiseProvider.get(db, topology) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought the idea was to remove every instance of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is my understanding that each time a method takes-in // here mongoClient sets `bluebird`
const client = await MongoClient("mongodb://127.0.0.1", {
promiseLibrary: bluebird,
useUnifiedTopology: true
});
const db = client.db("test");
// here in collection I'm setting the promiseLibrary to `q`
const collectionPromise = db.collection("test", { promiseLibrary: q }).find().toArray(); I would assume here the driver would provide any promises coming from This is the "parody" i believed we we were trying to support in 3.6 If we use a "global" setter / getter, and don't store in-parent-class and pass options, we loose this tracking of what class is using what. My plan was to remove the stores in master and only This is related to the private-slack thread here. |
||
}; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
'use strict'; | ||
|
||
const PromiseProvider = require('./promise_provider'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just wanted to point out that this class has been refactored to use |
||
const EventEmitter = require('events'); | ||
const isResumableError = require('./error').isResumableError; | ||
const MongoError = require('./core').MongoError; | ||
|
@@ -85,7 +86,7 @@ class ChangeStream extends EventEmitter { | |
); | ||
} | ||
|
||
this.promiseLibrary = parent.s.promiseLibrary; | ||
this.promiseLibrary = PromiseProvider.get(options, parent); | ||
if (!this.options.readPreference && parent.s.readPreference) { | ||
this.options.readPreference = parent.s.readPreference; | ||
} | ||
|
@@ -138,10 +139,11 @@ class ChangeStream extends EventEmitter { | |
* @return {Promise} returns Promise if no callback passed | ||
*/ | ||
next(callback) { | ||
var self = this; | ||
const self = this; | ||
const Promise = PromiseProvider.get(self); | ||
if (this.isClosed()) { | ||
if (callback) return callback(new Error('Change Stream is not open.'), null); | ||
return self.promiseLibrary.reject(new Error('Change Stream is not open.')); | ||
return Promise.reject(new Error('Change Stream is not open.')); | ||
} | ||
|
||
return this.cursor | ||
|
@@ -169,9 +171,11 @@ class ChangeStream extends EventEmitter { | |
* @return {Promise} returns Promise if no callback passed | ||
*/ | ||
close(callback) { | ||
const Promise = PromiseProvider.get(this); | ||
|
||
if (!this.cursor) { | ||
if (callback) return callback(); | ||
return this.promiseLibrary.resolve(); | ||
return Promise.resolve(); | ||
} | ||
|
||
// Tidy up the existing cursor | ||
|
@@ -186,7 +190,7 @@ class ChangeStream extends EventEmitter { | |
}); | ||
} | ||
|
||
const PromiseCtor = this.promiseLibrary || Promise; | ||
const PromiseCtor = PromiseProvider.get(this); | ||
return new PromiseCtor((resolve, reject) => { | ||
cursor.close(err => { | ||
['data', 'close', 'end', 'error'].forEach(event => cursor.removeAllListeners(event)); | ||
|
@@ -472,6 +476,7 @@ function waitForTopologyConnected(topology, options, callback) { | |
// Handle new change events. This method brings together the routes from the callback, event emitter, and promise ways of using ChangeStream. | ||
function processNewChange(args) { | ||
const changeStream = args.changeStream; | ||
const Promise = PromiseProvider.get(changeStream); | ||
const error = args.error; | ||
const change = args.change; | ||
const callback = args.callback; | ||
|
@@ -486,9 +491,7 @@ function processNewChange(args) { | |
} | ||
|
||
const error = new MongoError('ChangeStream is closed'); | ||
return typeof callback === 'function' | ||
? callback(error, null) | ||
: changeStream.promiseLibrary.reject(error); | ||
return typeof callback === 'function' ? callback(error, null) : Promise.reject(error); | ||
} | ||
|
||
const topology = changeStream.topology; | ||
|
@@ -546,7 +549,7 @@ function processNewChange(args) { | |
|
||
if (eventEmitter) return changeStream.emit('error', error); | ||
if (typeof callback === 'function') return callback(error, null); | ||
return changeStream.promiseLibrary.reject(error); | ||
return Promise.reject(error); | ||
} | ||
|
||
changeStream.attemptingResume = false; | ||
|
@@ -558,7 +561,7 @@ function processNewChange(args) { | |
|
||
if (eventEmitter) return changeStream.emit('error', noResumeTokenError); | ||
if (typeof callback === 'function') return callback(noResumeTokenError, null); | ||
return changeStream.promiseLibrary.reject(noResumeTokenError); | ||
return Promise.reject(noResumeTokenError); | ||
} | ||
|
||
// cache the resume token | ||
|
@@ -571,7 +574,7 @@ function processNewChange(args) { | |
// Return the change | ||
if (eventEmitter) return changeStream.emit('change', change); | ||
if (typeof callback === 'function') return callback(error, change); | ||
return changeStream.promiseLibrary.resolve(change); | ||
return Promise.resolve(change); | ||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
'use strict'; | ||
|
||
const PromiseProvider = require('./promise_provider'); | ||
const deprecate = require('util').deprecate; | ||
const deprecateOptions = require('./utils').deprecateOptions; | ||
const checkCollectionName = require('./utils').checkCollectionName; | ||
|
@@ -128,7 +129,7 @@ function Collection(db, topology, dbName, name, pkFactory, options) { | |
const namespace = new MongoDBNamespace(dbName, name); | ||
|
||
// Get the promiseLibrary | ||
const promiseLibrary = options.promiseLibrary || Promise; | ||
const promiseLibrary = PromiseProvider.get(options, db, topology); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here's a case that I'm taking about. It's a little more comprehensive than it previously was. I read this as, check the |
||
|
||
// Set custom primary key factory if provided | ||
pkFactory = pkFactory == null ? ObjectID : pkFactory; | ||
|
@@ -443,7 +444,7 @@ Collection.prototype.find = deprecateOptions( | |
newOptions.db = this.s.db; | ||
|
||
// Add the promise library | ||
newOptions.promiseLibrary = this.s.promiseLibrary; | ||
newOptions.promiseLibrary = PromiseProvider.get(options, this); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is within There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I'm understanding things correctly, in order to keep the behavior unchanged here for Any methods in |
||
|
||
// Set raw if available at collection level | ||
if (newOptions.raw == null && typeof this.s.raw === 'boolean') newOptions.raw = this.s.raw; | ||
|
@@ -748,13 +749,14 @@ Collection.prototype.insert = deprecate(function(docs, options, callback) { | |
* @return {Promise} returns Promise if no callback passed | ||
*/ | ||
Collection.prototype.updateOne = function(filter, update, options, callback) { | ||
const Promise = PromiseProvider.get(this); | ||
if (typeof options === 'function') (callback = options), (options = {}); | ||
options = options || {}; | ||
|
||
const err = checkForAtomicOperators(update); | ||
if (err) { | ||
if (typeof callback === 'function') return callback(err); | ||
return this.s.promiseLibrary.reject(err); | ||
return Promise.reject(err); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these are frustrating.. they should really be deferred to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should that change be in this PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no, just calling it out |
||
} | ||
|
||
options = Object.assign({}, options); | ||
|
@@ -827,13 +829,14 @@ Collection.prototype.replaceOne = function(filter, doc, options, callback) { | |
* @return {Promise<Collection~updateWriteOpResult>} returns Promise if no callback passed | ||
*/ | ||
Collection.prototype.updateMany = function(filter, update, options, callback) { | ||
const Promise = PromiseProvider.get(this); | ||
if (typeof options === 'function') (callback = options), (options = {}); | ||
options = options || {}; | ||
|
||
const err = checkForAtomicOperators(update); | ||
if (err) { | ||
if (typeof callback === 'function') return callback(err); | ||
return this.s.promiseLibrary.reject(err); | ||
return Promise.reject(err); | ||
} | ||
|
||
options = Object.assign({}, options); | ||
|
@@ -1754,6 +1757,7 @@ Collection.prototype.findOneAndReplace = function(filter, replacement, options, | |
* @return {Promise<Collection~findAndModifyWriteOpResultObject>} returns Promise if no callback passed | ||
*/ | ||
Collection.prototype.findOneAndUpdate = function(filter, update, options, callback) { | ||
const Promise = PromiseProvider.get(this); | ||
if (typeof options === 'function') (callback = options), (options = {}); | ||
options = options || {}; | ||
|
||
|
@@ -1766,7 +1770,7 @@ Collection.prototype.findOneAndUpdate = function(filter, update, options, callba | |
const err = checkForAtomicOperators(update); | ||
if (err) { | ||
if (typeof callback === 'function') return callback(err); | ||
return this.s.promiseLibrary.reject(err); | ||
return Promise.reject(err); | ||
} | ||
|
||
const findOneAndUpdateOperation = new FindOneAndUpdateOperation(this, filter, update, options); | ||
|
@@ -1990,7 +1994,7 @@ Collection.prototype.parallelCollectionScan = deprecate(function(options, callba | |
options.readPreference = resolveReadPreference(this, options); | ||
|
||
// Add a promiseLibrary | ||
options.promiseLibrary = this.s.promiseLibrary; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a little confused about what setting |
||
options.promiseLibrary = PromiseProvider.get(this); | ||
|
||
if (options.session) { | ||
options.session = undefined; | ||
|
@@ -2171,7 +2175,7 @@ Collection.prototype.initializeUnorderedBulkOp = function(options) { | |
options.ignoreUndefined = this.s.options.ignoreUndefined; | ||
} | ||
|
||
options.promiseLibrary = this.s.promiseLibrary; | ||
options.promiseLibrary = PromiseProvider.get(this); | ||
return unordered(this.s.topology, this, options); | ||
}; | ||
|
||
|
@@ -2194,7 +2198,7 @@ Collection.prototype.initializeOrderedBulkOp = function(options) { | |
if (options.ignoreUndefined == null) { | ||
options.ignoreUndefined = this.s.options.ignoreUndefined; | ||
} | ||
options.promiseLibrary = this.s.promiseLibrary; | ||
options.promiseLibrary = PromiseProvider.get(this); | ||
return ordered(this.s.topology, this, options); | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
'use strict'; | ||
|
||
const PromiseProvider = require('../../promise_provider'); | ||
const Denque = require('denque'); | ||
const EventEmitter = require('events'); | ||
const ServerDescription = require('./server_description').ServerDescription; | ||
|
@@ -193,7 +195,7 @@ class Topology extends EventEmitter { | |
// Active client sessions | ||
sessions: new Set(), | ||
// Promise library | ||
promiseLibrary: options.promiseLibrary || Promise, | ||
promiseLibrary: PromiseProvider.get(options), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A user can't create a |
||
credentials: options.credentials, | ||
clusterTime: null, | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
'use strict'; | ||
|
||
const PromiseProvider = require('./promise_provider'); | ||
const Transform = require('stream').Transform; | ||
const PassThrough = require('stream').PassThrough; | ||
const deprecate = require('util').deprecate; | ||
|
@@ -111,7 +112,7 @@ class Cursor extends CoreCursor { | |
const currentNumberOfRetries = numberOfRetries; | ||
|
||
// Get the promiseLibrary | ||
const promiseLibrary = options.promiseLibrary || Promise; | ||
const promiseLibrary = PromiseProvider.get(options, topology); | ||
|
||
// Internal cursor state | ||
this.s = { | ||
|
@@ -727,6 +728,7 @@ class Cursor extends CoreCursor { | |
* @return {Promise} if no callback supplied | ||
*/ | ||
forEach(iterator, callback) { | ||
const Promise = PromiseProvider.get(this); | ||
// Rewind cursor state | ||
this.rewind(); | ||
|
||
|
@@ -751,7 +753,7 @@ class Cursor extends CoreCursor { | |
} | ||
}); | ||
} else { | ||
return new this.s.promiseLibrary((fulfill, reject) => { | ||
return new Promise((fulfill, reject) => { | ||
each(this, (err, doc) => { | ||
if (err) { | ||
reject(err); | ||
|
@@ -910,6 +912,7 @@ class Cursor extends CoreCursor { | |
* @return {Promise} returns Promise if no callback passed | ||
*/ | ||
close(options, callback) { | ||
const Promise = PromiseProvider.get(this); | ||
if (typeof options === 'function') (callback = options), (options = {}); | ||
options = Object.assign({}, { skipKillCursors: false }, options); | ||
|
||
|
@@ -929,17 +932,15 @@ class Cursor extends CoreCursor { | |
} | ||
|
||
// Return a Promise | ||
return new this.s.promiseLibrary(resolve => { | ||
resolve(); | ||
}); | ||
return Promise.resolve(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was an opinionated change, no reason to call new here just to resolve. |
||
}; | ||
|
||
if (this.cursorState.session) { | ||
if (typeof callback === 'function') { | ||
return this._endSession(() => completeClose()); | ||
} | ||
|
||
return new this.s.promiseLibrary(resolve => { | ||
return new Promise(resolve => { | ||
this._endSession(() => completeClose().then(resolve)); | ||
}); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had the idea of removing this
promiseLibrary
option, and rather just pull it out ofdb
.