From bce0de4a4f61bfca1c60175f0e576b7924db83a6 Mon Sep 17 00:00:00 2001 From: 0x0a0d Date: Tue, 20 Dec 2022 19:13:58 +0700 Subject: [PATCH 1/2] use this.model.db as NativeConnection instance --- .github/workflows/ci.yml | 8 +- package.json | 1 - .../src/index.js | 111 ++++++++++-------- .../test/unit/index.spec.js | 28 ++--- 4 files changed, 79 insertions(+), 69 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42344767..aec36451 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,8 +35,12 @@ jobs: ${{ runner.os }}- - name: Install dependencies - run: npm run setup-no-old-node - if: ${{ matrix.node-version == '10.x' || matrix.node-version == '12.x' }} + run: npm install && lerna bootstrap --ignore moleculer-db-adapter-prisma --ignore moleculer-db-adapter-mongoose + if: ${{ matrix.node-version == '10.x' }} + + - name: Install dependencies + run: npm install && lerna bootstrap --ignore moleculer-db-adapter-prisma + if: ${{ matrix.node-version == '12.x' }} - name: Install dependencies run: npm run setup diff --git a/package.json b/package.json index 86df6e44..7e0d6249 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,6 @@ "version": "1.0.0", "scripts": { "setup": "npm install && lerna bootstrap", - "setup-no-old-node": "npm install && lerna bootstrap --ignore moleculer-db-adapter-prisma --ignore moleculer-db-adapter-mongoose", "clean": "lerna clean", "dev": "nodemon dev.js", "demo": "node dev.js", diff --git a/packages/moleculer-db-adapter-mongoose/src/index.js b/packages/moleculer-db-adapter-mongoose/src/index.js index d33cb9b4..c2ba719c 100644 --- a/packages/moleculer-db-adapter-mongoose/src/index.js +++ b/packages/moleculer-db-adapter-mongoose/src/index.js @@ -64,64 +64,63 @@ class MongooseDbAdapter { * @memberof MongooseDbAdapter */ connect() { - let conn; - - if (this.model) { + return new Promise((resolve) => { + if (this.model) { + // model field exists in service schema, should check if model has been connected + if (this.model.db) { + // if this.model.db is existed, adapter had connected before, just return this.model.db + // Model.prototype.db + // Connection the model uses. + // https://mongoosejs.com/docs/api/model.html#model_Model-db + resolve(this.model.db); + return; + } + /* istanbul ignore next */ + if ( + mongoose.connection.readyState === mongoose.connection.states.connected || + mongoose.connection.readyState === mongoose.connection.states.connecting + ) { + // if mongoose is connecting, will handle below + resolve(mongoose.connection); + } else { + // everything else cases mean we not yet do connect before, make it + const conn = mongoose.createConnection(this.uri, this.opts); + resolve(conn); + } + } else if (this.schema) { + const conn = mongoose.createConnection(this.uri, this.opts); - /* istanbul ignore next */ - if (mongoose.connection.readyState == 1) { - this.db = mongoose.connection; - return Promise.resolve(); - } else if (mongoose.connection.readyState == 2) { - conn = Promise.resolve(mongoose.connection); - } else { - conn = mongoose.connect(this.uri, this.opts); + this.model = conn.model(this.modelName, this.schema); + resolve(conn); } - - } else if (this.schema) { - conn = new Promise(resolve =>{ - const c = mongoose.createConnection(this.uri, this.opts); - this.model = c.model(this.modelName, this.schema); - resolve(c); - }); - } - - - return conn.then(_result => { - const result = _result || conn; - this.conn = conn; - - if (mongoose.connection.readyState != mongoose.connection.states.connected) { - throw new MoleculerError( - `MongoDB connection failed . Status is "${ - mongoose.connection.states[mongoose.connection._readyState] - }"` - ); + }).then(conn => { + this.conn = conn; + + if (this.conn.db != null) { + return this.conn.db; + } else if (this.conn.readyState === mongoose.connection.states.connecting) { + return new Promise((resolve, reject) => { + this.conn.once("error", reject); + this.conn.once("connected", () => { + this.conn.removeListener("error", reject); + resolve(this.conn.db); + }); + }); } - if(this.model) - this.model = _result.model(this.model["modelName"],this.model["schema"]); - - - if (result.connection) - this.db = result.connection.db; - else - this.db = result.db; - - if (!this.db) { - throw new MoleculerError("MongoDB connection failed to get DB object"); - } + throw new MoleculerError("MongoDB connection failed to get DB object"); + }).then(db => { + this.db = db; this.service.logger.info("MongoDB adapter has connected successfully."); - + // do not use this.db.on() because of next line + // DeprecationWarning: Listening to events on the Db class has been deprecated and will be removed in the next major version. /* istanbul ignore next */ - result.connection.on("disconnected", () => this.service.logger.warn("Mongoose adapter has disconnected.")); - result.connection.on("error", err => this.service.logger.error("MongoDB error.", err)); - result.connection.on("reconnect", () => this.service.logger.info("Mongoose adapter has reconnected.")); - + this.conn.on("disconnected", () => this.service.logger.warn("Mongoose adapter has disconnected.")); + this.conn.on("error", err => this.service.logger.error("MongoDB error.", err)); + this.conn.on("reconnect", () => this.service.logger.info("Mongoose adapter has reconnected.")); }); - } /** @@ -133,11 +132,19 @@ class MongooseDbAdapter { */ disconnect() { return new Promise(resolve => { - if (this.db && this.db.close) { - this.db.close(resolve); - } else if (this.conn && this.conn.close) { + if (this.conn == null) { + // model was created and mongoose maybe connected before call .connect() + mongoose.connection.close(resolve); + } else if (this.conn.readyState === mongoose.connection.states.connecting) { + // disconnect() was called before connect() success + // try to disconnect at nextTick + setTimeout(() => resolve(this.disconnect()), 0); + } else if (this.conn.close) { this.conn.close(resolve); + } else if (this.db != null && this.db.close) { + this.db.close(resolve); } else { + // for unknown cases mongoose.connection.close(resolve); } }); diff --git a/packages/moleculer-db-adapter-mongoose/test/unit/index.spec.js b/packages/moleculer-db-adapter-mongoose/test/unit/index.spec.js index 99bd6ea7..1a0147cd 100644 --- a/packages/moleculer-db-adapter-mongoose/test/unit/index.spec.js +++ b/packages/moleculer-db-adapter-mongoose/test/unit/index.spec.js @@ -139,13 +139,12 @@ if (process.versions.node.split(".")[0] < 14) { beforeEach(() => { mongoose.connection.readyState = mongoose.connection.states.disconnected; - mongoose.connect = jest.fn(() => { - mongoose.connection.readyState = - mongoose.connection.states.connected; - return Promise.resolve({ - connection: { ...fakeDb, db: fakeDb }, - model: jest.fn(() => fakeModel), - }); + mongoose.createConnection = jest.fn(() => { + return { + ...fakeDb, + db: fakeDb, + readyState: mongoose.connection.states.connected, + }; }); }); @@ -153,14 +152,14 @@ if (process.versions.node.split(".")[0] < 14) { fakeDb.on.mockClear(); adapter.opts = undefined; - adapter.model = jest.fn(() => fakeModel); + adapter.model = fakeModel; return adapter .connect() .catch(protectReject) .then(() => { - expect(mongoose.connect).toHaveBeenCalledTimes(1); - expect(mongoose.connect).toHaveBeenCalledWith( + expect(mongoose.createConnection).toHaveBeenCalledTimes(1); + expect(mongoose.createConnection).toHaveBeenCalledWith( "mongodb://localhost", undefined ); @@ -190,8 +189,8 @@ if (process.versions.node.split(".")[0] < 14) { .connect() .catch(protectReject) .then(() => { - expect(mongoose.connect).toHaveBeenCalledTimes(1); - expect(mongoose.connect).toHaveBeenCalledWith( + expect(mongoose.createConnection).toHaveBeenCalledTimes(1); + expect(mongoose.createConnection).toHaveBeenCalledWith( adapter.uri, adapter.opts ); @@ -250,8 +249,9 @@ if (process.versions.node.split(".")[0] < 14) { mongoose.connection.readyState = mongoose.connection.states.connected; return { - connection: { db: fakeDb, ...fakeDb }, - model: jest.fn(() => fakeModel), + db: fakeDb, + ...fakeDb, + readyState: mongoose.connection.states.connected }; }); From 81f4f3f1f9ab8e05036a6192851d320712f6f1a3 Mon Sep 17 00:00:00 2001 From: 0x0a0d Date: Tue, 20 Dec 2022 21:03:16 +0700 Subject: [PATCH 2/2] restore test mongoose on node12 --- packages/moleculer-db-adapter-mongoose/test/unit/index.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/moleculer-db-adapter-mongoose/test/unit/index.spec.js b/packages/moleculer-db-adapter-mongoose/test/unit/index.spec.js index 1a0147cd..8f2f283b 100644 --- a/packages/moleculer-db-adapter-mongoose/test/unit/index.spec.js +++ b/packages/moleculer-db-adapter-mongoose/test/unit/index.spec.js @@ -1,5 +1,5 @@ "use strict"; -if (process.versions.node.split(".")[0] < 14) { +if (process.versions.node.split(".")[0] < 12) { console.log("Skipping Mongoose tests because node version is too low"); it("Skipping Mongoose tests because node version is too low", () => {}); } else {