Skip to content

Commit eed1131

Browse files
authored
refactor(db)!: suppress Db events (#2251)
Db class no longer emits events, only MongoClient does now. Also removed parent/child relationships for databases. NODE-1709
1 parent 77442f8 commit eed1131

File tree

6 files changed

+11
-185
lines changed

6 files changed

+11
-185
lines changed

lib/db.js

+1-92
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

3-
const EventEmitter = require('events');
4-
const { inherits, deprecate } = require('util');
3+
const { deprecate } = require('util');
54
const { AggregationCursor, CommandCursor } = require('./cursor');
65
const { ObjectID } = require('./utils').retrieveBSON();
76
const ReadPreference = require('./read_preference');
@@ -26,7 +25,6 @@ const {
2625

2726
// Operations
2827
const {
29-
createListener,
3028
ensureIndex,
3129
evaluate,
3230
profilingInfo,
@@ -88,7 +86,6 @@ const legalOptionNames = [
8886
'readConcern',
8987
'retryMiliSeconds',
9088
'numberOfRetries',
91-
'parentDb',
9289
'noListener',
9390
'loggerLevel',
9491
'logger',
@@ -130,18 +127,11 @@ const legalOptionNames = [
130127
* @property {boolean} slaveOk The current slaveOk value for the db instance.
131128
* @property {object} writeConcern The current write concern values.
132129
* @property {object} topology Access the topology object (single server, replicaset or mongos).
133-
* @fires Db#close
134-
* @fires Db#reconnect
135-
* @fires Db#error
136-
* @fires Db#timeout
137-
* @fires Db#parseError
138-
* @fires Db#fullsetup
139130
* @return {Db} a Db instance.
140131
*/
141132
function Db(databaseName, topology, options) {
142133
options = options || {};
143134
if (!(this instanceof Db)) return new Db(databaseName, topology, options);
144-
EventEmitter.call(this);
145135

146136
// Get the promiseLibrary
147137
const promiseLibrary = options.promiseLibrary || Promise;
@@ -156,8 +146,6 @@ function Db(databaseName, topology, options) {
156146
this.s = {
157147
// DbCache
158148
dbCache: {},
159-
// Children db's
160-
children: [],
161149
// Topology
162150
topology: topology,
163151
// Options
@@ -170,8 +158,6 @@ function Db(databaseName, topology, options) {
170158
readPreference: ReadPreference.fromOptions(options),
171159
// Set buffermaxEntries
172160
bufferMaxEntries: typeof options.bufferMaxEntries === 'number' ? options.bufferMaxEntries : -1,
173-
// Parent db (if chained)
174-
parentDb: options.parentDb || null,
175161
// Set up the primary key factory or fallback to ObjectID
176162
pkFactory: options.pkFactory || ObjectID,
177163
// Get native parser
@@ -195,23 +181,9 @@ function Db(databaseName, topology, options) {
195181
getSingleProperty(this, 'bufferMaxEntries', this.s.bufferMaxEntries);
196182
getSingleProperty(this, 'databaseName', this.s.namespace.db);
197183

198-
// This is a child db, do not register any listeners
199-
if (options.parentDb) return;
200184
if (this.s.noListener) return;
201-
202-
// Add listeners
203-
topology.on('error', createListener(this, 'error', this));
204-
topology.on('timeout', createListener(this, 'timeout', this));
205-
topology.on('close', createListener(this, 'close', this));
206-
topology.on('parseError', createListener(this, 'parseError', this));
207-
topology.once('open', createListener(this, 'open', this));
208-
topology.once('fullsetup', createListener(this, 'fullsetup', this));
209-
topology.once('all', createListener(this, 'all', this));
210-
topology.on('reconnect', createListener(this, 'reconnect', this));
211185
}
212186

213-
inherits(Db, EventEmitter);
214-
215187
// Topology
216188
Object.defineProperty(Db.prototype, 'topology', {
217189
enumerable: true,
@@ -789,11 +761,6 @@ Db.prototype.ensureIndex = deprecate(function(name, fieldOrSpec, options, callba
789761
]);
790762
}, 'Db.ensureIndex is deprecated as of MongoDB version 3.0 / driver version 2.0');
791763

792-
Db.prototype.addChild = function(db) {
793-
if (this.s.parentDb) return this.s.parentDb.addChild(db);
794-
this.s.children.push(db);
795-
};
796-
797764
/**
798765
* Add a user to the database.
799766
* @method
@@ -963,64 +930,6 @@ Db.prototype.getLogger = function() {
963930
return this.s.logger;
964931
};
965932

966-
/**
967-
* Db close event
968-
*
969-
* Emitted after a socket closed against a single server or mongos proxy.
970-
*
971-
* @event Db#close
972-
* @type {MongoError}
973-
*/
974-
975-
/**
976-
* Db reconnect event
977-
*
978-
* * Server: Emitted when the driver has reconnected and re-authenticated.
979-
* * ReplicaSet: N/A
980-
* * Mongos: Emitted when the driver reconnects and re-authenticates successfully against a Mongos.
981-
*
982-
* @event Db#reconnect
983-
* @type {object}
984-
*/
985-
986-
/**
987-
* Db error event
988-
*
989-
* Emitted after an error occurred against a single server or mongos proxy.
990-
*
991-
* @event Db#error
992-
* @type {MongoError}
993-
*/
994-
995-
/**
996-
* Db timeout event
997-
*
998-
* Emitted after a socket timeout occurred against a single server or mongos proxy.
999-
*
1000-
* @event Db#timeout
1001-
* @type {MongoError}
1002-
*/
1003-
1004-
/**
1005-
* Db parseError event
1006-
*
1007-
* The parseError event is emitted if the driver detects illegal or corrupt BSON being received from the server.
1008-
*
1009-
* @event Db#parseError
1010-
* @type {MongoError}
1011-
*/
1012-
1013-
/**
1014-
* Db fullsetup event, emitted when all servers in the topology have been connected to at start up time.
1015-
*
1016-
* * Server: Emitted when the driver has connected to the single server and has authenticated.
1017-
* * ReplSet: Emitted after the driver has attempted to connect to all replicaset members.
1018-
* * Mongos: Emitted after the driver has attempted to connect to all mongos proxies.
1019-
*
1020-
* @event Db#fullsetup
1021-
* @type {Db}
1022-
*/
1023-
1024933
// Constants
1025934
Db.SYSTEM_NAMESPACE_COLLECTION = CONSTANTS.SYSTEM_NAMESPACE_COLLECTION;
1026935
Db.SYSTEM_INDEX_COLLECTION = CONSTANTS.SYSTEM_INDEX_COLLECTION;

lib/mongo_client.js

+5-20
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ const ChangeStream = require('./change_stream');
66
const ReadPreference = require('./read_preference');
77
const { MongoError } = require('./error');
88
const WriteConcern = require('./write_concern');
9-
const NativeTopology = require('./topologies/native_topology');
109
const { maybePromise, MongoDBNamespace } = require('./utils');
1110
const { inherits, deprecate } = require('util');
1211
const { connect, validOptions } = require('./operations/connect');
@@ -241,40 +240,26 @@ MongoClient.prototype.close = function(force, callback) {
241240

242241
const client = this;
243242
return maybePromise(callback, cb => {
244-
const completeClose = err => {
245-
client.emit('close', client);
246-
247-
if (!(client.topology instanceof NativeTopology)) {
248-
for (const item of client.s.dbCache) {
249-
item[1].emit('close', client);
250-
}
251-
}
252-
253-
client.removeAllListeners('close');
254-
cb(err);
255-
};
256-
257243
if (client.topology == null) {
258-
completeClose();
244+
cb();
259245
return;
260246
}
261247

262248
client.topology.close(force, err => {
263249
const autoEncrypter = client.topology.s.options.autoEncrypter;
264250
if (!autoEncrypter) {
265-
completeClose(err);
251+
cb(err);
266252
return;
267253
}
268254

269-
autoEncrypter.teardown(force, err2 => completeClose(err || err2));
255+
autoEncrypter.teardown(force, err2 => cb(err || err2));
270256
});
271257
});
272258
};
273259

274260
/**
275-
* Create a new Db instance sharing the current socket connections. Be aware that the new db instances are
276-
* related in a parent-child relationship to the original instance so that events are correctly emitted on child
277-
* db instances. Child db instances are cached so performing db('db1') twice will return the same instance.
261+
* Create a new Db instance sharing the current socket connections.
262+
* Db instances are cached so performing db('db1') twice will return the same instance.
278263
* You can control these behaviors with the options noListener and returnNonCachedInstance.
279264
*
280265
* @method

lib/operations/command.js

-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ const debugFields = [
2828
'retryMiliSeconds',
2929
'readPreference',
3030
'pkFactory',
31-
'parentDb',
3231
'promiseLibrary',
3332
'noListener'
3433
];

lib/operations/db_ops.js

-6
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ const debugFields = [
4848
'retryMiliSeconds',
4949
'readPreference',
5050
'pkFactory',
51-
'parentDb',
5251
'promiseLibrary',
5352
'noListener'
5453
];
@@ -236,11 +235,6 @@ function createListener(db, e, object) {
236235
function listener(err) {
237236
if (object.listeners(e).length > 0) {
238237
object.emit(e, err, db);
239-
240-
// Emit on all associated db's if available
241-
for (let i = 0; i < db.s.children.length; i++) {
242-
db.s.children[i].emit(e, err, db.s.children[i]);
243-
}
244238
}
245239
}
246240
return listener;

test/functional/multiple_db.test.js

-60
Original file line numberDiff line numberDiff line change
@@ -7,66 +7,6 @@ describe('Multiple Databases', function() {
77
return setupDatabase(this.configuration);
88
});
99

10-
/**
11-
* @ignore
12-
*/
13-
it('shouldCorrectlyEmitErrorOnAllDbsOnPoolClose', {
14-
// Add a tag that our runner can trigger on
15-
// in this case we are setting that node needs to be higher than 0.10.X to run
16-
metadata: { requires: { topology: 'single' } },
17-
18-
// The actual test we wish to run
19-
test: function(done) {
20-
if (process.platform !== 'linux') {
21-
var configuration = this.configuration;
22-
var client = configuration.newClient({ w: 1 }, { poolSize: 1 });
23-
24-
// All inserted docs
25-
var numberOfCloses = 0;
26-
27-
// Start server
28-
client.on('close', function(err) {
29-
test.ok(err !== null);
30-
numberOfCloses = numberOfCloses + 1;
31-
});
32-
33-
client.connect(function(err, client) {
34-
var db = client.db(configuration.db);
35-
36-
db.createCollection('shouldCorrectlyErrorOnAllDbs', function(err, collection) {
37-
test.equal(null, err);
38-
39-
collection.insert({ a: 1 }, { w: 1 }, function(err) {
40-
test.equal(null, err);
41-
// Open a second db
42-
var db2 = client.db('tests_2');
43-
// Add a close handler
44-
db2.on('close', function(err) {
45-
test.ok(err !== null);
46-
numberOfCloses = numberOfCloses + 1;
47-
test.equal(2, numberOfCloses);
48-
});
49-
50-
// Open a second db
51-
var db3 = client.db('tests_3');
52-
// Add a close handler
53-
db3.on('close', function(err) {
54-
test.ok(err !== null);
55-
numberOfCloses = numberOfCloses + 1;
56-
test.equal(3, numberOfCloses);
57-
done();
58-
});
59-
60-
client.close();
61-
});
62-
});
63-
});
64-
} else {
65-
done();
66-
}
67-
}
68-
});
69-
7010
/**
7111
* Test the auto connect functionality of the db
7212
*

test/functional/operation_example.test.js

+5-6
Original file line numberDiff line numberDiff line change
@@ -3615,6 +3615,10 @@ describe('Operation Examples', function() {
36153615
test: function(done) {
36163616
var configuration = this.configuration;
36173617
var client = configuration.newClient(configuration.writeConcernMax(), { poolSize: 1 });
3618+
// NODE-2484: investigate double close event in Unified Topology environment
3619+
// client.on('close', function() {
3620+
// done();
3621+
// });
36183622
client.connect(function(err, client) {
36193623
// LINE var MongoClient = require('mongodb').MongoClient,
36203624
// LINE test = require('assert');
@@ -3626,14 +3630,9 @@ describe('Operation Examples', function() {
36263630
// REMOVE-LINE done();
36273631
// REMOVE-LINE var db = client.db(configuration.db);
36283632
// BEGIN
3629-
var db = client.db(configuration.db);
36303633
test.equal(null, err);
36313634

3632-
db.on('close', function() {
3633-
done();
3634-
});
3635-
3636-
client.close();
3635+
client.close(done);
36373636
});
36383637
// END
36393638
}

0 commit comments

Comments
 (0)