Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.88k stars 3.83k forks source link

Feature: Option to disable creation of initial connection #12965

Closed titanism closed 1 year ago

titanism commented 1 year ago

Prerequisites

🚀 Feature Proposal

If you manage multiple custom connections, a typical pattern is to simply create new connections with createConnection(uri, options). Doing so, it adds by default to the mongoose singleton of mongoose.connections, so you can iterate over mongoose.connections to see properties such as readyState.

The default connection however is always present. The only way to delete it (regardless of custom Mongoose instances) is to manually call mongoose.connection.destroy();. This isn't such a good pattern, as a better option might be new Mongoose({ createInitialConnection: false }); or something. Adding this feature would require some refactoring though.

titanism commented 1 year ago

This might not actually be too hard, but we could be wrong:

  // default global options
  this.options = Object.assign({
    pluralization: true,
    autoIndex: true,
-    autoCreate: true
+    autoCreate: true,
+    createInitialConnection: false
  }, options);
+
+  if (this.options.createInitialConnection) {
+    const conn = this.createConnection(); // default connection
+    conn.models = this.models;
+  }

-  const conn = this.createConnection(); // default connection
-  conn.models = this.models;
titanism commented 1 year ago

There might also be another bug here we discovered, whereas id is not unique.

https://github.com/Automattic/mongoose/blob/9d7bf10606e567990969aabe130f16b896e2d29b/lib/connection.js#L72-L76

If you create multiple connections, then call .destroy() on them, and then create more connections, multiple of the connections will have the same id property because .length does not check for uniqueness.

cc @vkarpov15

titanism commented 1 year ago

Confirmed this is a bug!

const mongoose = require('mongoose');
mongoose.createConnection()
mongoose.createConnection()
mongoose.connections[0].destroy()
mongoose.createConnection()
mongoose.createConnection()
mongoose.createConnection()
mongoose.connections.map(c => c.id) // outputs: [ 1, 2, 3, 3, 4 ]

You can see 3 appears twice.