-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
fix: allow connect again after close #2355
Conversation
@@ -68,7 +68,7 @@ | |||
"test": "npm run lint && mocha --recursive test/functional test/unit test/core", | |||
"test-nolint": "mocha --recursive test/functional test/unit test/core", | |||
"coverage": "istanbul cover mongodb-test-runner -- -t 60000 test/core test/unit test/functional", | |||
"lint": "eslint lib test", | |||
"lint": "eslint -v && eslint lib test", |
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.
Unrelated to this PR. I just sometimes get weird discrepancies between running eslint
locally and what runs on evergreen. Was thinking adding this could help make things a bit more explicit around the version of eslint
being used, when it is being used.
[ -s "${NVM_DIR}/nvm.sh" ] && \. "${NVM_DIR}/nvm.sh" | ||
nvm install --lts=${NODE_LTS_NAME} | ||
nvm install --no-progress --lts=${NODE_LTS_NAME} |
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.
I upgraded nvm
so we can use the newish --no-progress
option.
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.
oh very nice 👏
[ -s "${NVM_DIR}/nvm.sh" ] && \. "${NVM_DIR}/nvm.sh" | ||
nvm install --lts=${NODE_LTS_NAME} | ||
nvm install --no-progress --lts=${NODE_LTS_NAME} |
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.
oh very nice 👏
lib/operations/connect.js
Outdated
// Has a connection already been established? | ||
if (mongoClient.topology) { | ||
if (mongoClient.topology.isConnected()) { | ||
throw new Error('already connected'); |
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.
I think this error message can be improved
@@ -241,28 +243,35 @@ MongoClient.prototype.close = function(force, callback) { | |||
force = false; | |||
} | |||
|
|||
const client = this; |
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.
We were using arrow functions everywhere here, so I just updated everything to use this
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.
iirc the reason client
was used is because this method has significant enough depth that this
can't be bound to the deepest nested functions. Can you confirm, for instance, that assignment to autoEncrypter
below is actually referencing the correct this
?
|
||
// clear out references to old topology | ||
this.topology = undefined; | ||
this.s.dbCache = new Map(); |
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.
the old dbCache
still references the old topology, so it is manually cleared out here in addition to this.topology
lib/mongo_client.js
Outdated
this.s.dbCache = new Map(); | ||
|
||
// restore options | ||
this.s.options = Object.assign({}, this.originalOptions); |
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.
this.s.options
can get mutated by connect
, so we need to restore it to what it was originally constructed with. Otherwise we get the following warnings, as reported in one of the issues:
the options [servers] is not supported
the options [caseTranslate] is not supported
the options [dbName] is not supported
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.
I would prefer that the small number of users using this functionality see those warnings than make all users pay to save off another copy of the options.
lib/mongo_client.js
Outdated
this.s.dbCache = new Map(); | ||
|
||
// restore options | ||
this.s.options = Object.assign({}, this.originalOptions); |
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.
I would prefer that the small number of users using this functionality see those warnings than make all users pay to save off another copy of the options.
@@ -241,28 +243,35 @@ MongoClient.prototype.close = function(force, callback) { | |||
force = false; | |||
} | |||
|
|||
const client = this; |
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.
iirc the reason client
was used is because this method has significant enough depth that this
can't be bound to the deepest nested functions. Can you confirm, for instance, that assignment to autoEncrypter
below is actually referencing the correct this
?
@@ -517,7 +517,7 @@ describe('Connection', function() { | |||
}); | |||
|
|||
it('should be able to connect again after close', function() { | |||
return withClient(this.configuration.newClient(), client => done => { | |||
return withClient.call(this, (client, done) => { |
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.
this should be equivalent to just calling withClient
within the scope, why was this change needed?
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.
Without it I get TypeError: Cannot read property 'configuration' of undefined
referencing this line.
test/functional/shared.js
Outdated
@@ -57,8 +57,37 @@ function setupDatabase(configuration, dbsToClean) { | |||
); | |||
} | |||
|
|||
function makeCleanupFn(client) { | |||
return function(err) { | |||
function withTempDb(name, options, client, operation, errorHandler) { |
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.
Similar to the change streams PR, I'd like to find a way not to wrap up withClient
calls into something that doesn't seem to create a client. At very least I think we should have composed naming for these methods, like withClientAndTempDb
, but maybe there's an even better way. Maybe we could end up with something like:
withClient(withTempDb((client, db, done) => {
}));
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.
I was actually working on this in a separate draft PR (#2362) so I pulled in my new withDb
helper.
Will open a new PR for this after #2362 is merged |
#2362 seems to have been merged. |
Description
connect
doesn't work again afterclose
has been called once on aMongoClient
.Cleaning up some state beforehand fixes the issue.
NODE-2544
What changed?
Also introduced some CI-related cleanup:
eslint
version before lintingnvm
and use--no-progress
option to clean up log outputI can split this out into a separate PR if desired.
Are there any files to ignore?