diff --git a/spec/GridFSBucketStorageAdapter.spec.js b/spec/GridFSBucketStorageAdapter.spec.js index 6ed4a92e..3abe73fd 100644 --- a/spec/GridFSBucketStorageAdapter.spec.js +++ b/spec/GridFSBucketStorageAdapter.spec.js @@ -60,4 +60,19 @@ describe('GridFSBucket and GridStore interop', () => { await gfsAdapter.deleteFile('myFileName'); await expectMissingFile(gfsAdapter, 'myFileName'); }); + + it('handleShutdown, close connection', done => { + const databaseURI = 'mongodb://localhost:27017/parse'; + const gfsAdapter = new GridFSBucketAdapter(databaseURI); + + gfsAdapter._connect().then(db => { + expect(db.serverConfig.connections().length > 0).toEqual(true); + expect(db.serverConfig.s.connected).toEqual(true); + gfsAdapter.handleShutdown().then(() => { + expect(db.serverConfig.connections().length > 0).toEqual(false); + expect(db.serverConfig.s.connected).toEqual(false); + done(); + }); + }); + }); }); diff --git a/spec/GridStoreAdapter.spec.js b/spec/GridStoreAdapter.spec.js index 1b6d6125..12f3938b 100644 --- a/spec/GridStoreAdapter.spec.js +++ b/spec/GridStoreAdapter.spec.js @@ -96,4 +96,19 @@ describe_only_db('mongo')('GridStoreAdapter', () => { }) .catch(fail); }); + + it('handleShutdown, close connection', done => { + const databaseURI = 'mongodb://localhost:27017/parse'; + const gridStoreAdapter = new GridStoreAdapter(databaseURI); + + gridStoreAdapter._connect().then(db => { + expect(db.serverConfig.connections().length > 0).toEqual(true); + expect(db.serverConfig.s.connected).toEqual(true); + gridStoreAdapter.handleShutdown().then(() => { + expect(db.serverConfig.connections().length > 0).toEqual(false); + expect(db.serverConfig.s.connected).toEqual(false); + done(); + }); + }); + }); }); diff --git a/spec/ParseServer.spec.js b/spec/ParseServer.spec.js index 00d7b347..bc98a4b7 100644 --- a/spec/ParseServer.spec.js +++ b/spec/ParseServer.spec.js @@ -66,14 +66,20 @@ describe('Server Url Checks', () => { const newConfiguration = Object.assign({}, defaultConfiguration, { databaseAdapter, serverStartComplete: () => { - parseServer.handleShutdown(); - parseServer.server.close(err => { - if (err) { - done.fail('Close Server Error'); - } - reconfigureServer({}).then(() => { - expect(close).toBe(true); - done(); + let promise = Promise.resolve(); + if (process.env.PARSE_SERVER_TEST_DB !== 'postgres') { + promise = parseServer.config.filesController.adapter._connect(); + } + promise.then(() => { + parseServer.handleShutdown(); + parseServer.server.close(err => { + if (err) { + done.fail('Close Server Error'); + } + reconfigureServer({}).then(() => { + expect(close).toBe(true); + done(); + }); }); }); }, diff --git a/src/Adapters/Files/GridFSBucketAdapter.js b/src/Adapters/Files/GridFSBucketAdapter.js index 883bf96c..3281fe93 100644 --- a/src/Adapters/Files/GridFSBucketAdapter.js +++ b/src/Adapters/Files/GridFSBucketAdapter.js @@ -32,7 +32,10 @@ export class GridFSBucketAdapter extends FilesAdapter { this._connectionPromise = MongoClient.connect( this._databaseURI, this._mongoOptions - ).then(client => client.db(client.s.options.dbName)); + ).then(client => { + this._client = client; + return client.db(client.s.options.dbName); + }); } return this._connectionPromise; } @@ -98,6 +101,13 @@ export class GridFSBucketAdapter extends FilesAdapter { const bucket = await this._getBucket(); return bucket.openDownloadStreamByName(filename); } + + handleShutdown() { + if (!this._client) { + return Promise.resolve(); + } + return this._client.close(false); + } } export default GridFSBucketAdapter; diff --git a/src/Adapters/Files/GridStoreAdapter.js b/src/Adapters/Files/GridStoreAdapter.js index e41abbc8..23f1668b 100644 --- a/src/Adapters/Files/GridStoreAdapter.js +++ b/src/Adapters/Files/GridStoreAdapter.js @@ -33,7 +33,10 @@ export class GridStoreAdapter extends FilesAdapter { this._connectionPromise = MongoClient.connect( this._databaseURI, this._mongoOptions - ).then(client => client.db(client.s.options.dbName)); + ).then(client => { + this._client = client; + return client.db(client.s.options.dbName); + }); } return this._connectionPromise; } @@ -99,6 +102,13 @@ export class GridStoreAdapter extends FilesAdapter { }); }); } + + handleShutdown() { + if (!this._client) { + return Promise.resolve(); + } + return this._client.close(false); + } } export default GridStoreAdapter; diff --git a/src/ParseServer.js b/src/ParseServer.js index b4e4cbdc..542e46ab 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -114,18 +114,22 @@ class ParseServer { } handleShutdown() { - const { adapter } = this.config.databaseController; - if (adapter && typeof adapter.handleShutdown === 'function') { - const promise = adapter.handleShutdown(); - if (promise instanceof Promise) { - return promise.then(() => { - if (this.config.serverCloseComplete) { - this.config.serverCloseComplete(); - } - }); - } + const promises = []; + const { adapter: databaseAdapter } = this.config.databaseController; + if ( + databaseAdapter && + typeof databaseAdapter.handleShutdown === 'function' + ) { + promises.push(databaseAdapter.handleShutdown()); } - return Promise.resolve().then(() => { + const { adapter: fileAdapter } = this.config.filesController; + if (fileAdapter && typeof fileAdapter.handleShutdown === 'function') { + promises.push(fileAdapter.handleShutdown()); + } + return (promises.length > 0 + ? Promise.all(promises) + : Promise.resolve() + ).then(() => { if (this.config.serverCloseComplete) { this.config.serverCloseComplete(); }