From ae94cb9c2a82cef93f9efdc83079bcfed0bab895 Mon Sep 17 00:00:00 2001 From: Matt Broadstone Date: Fri, 23 Aug 2019 19:51:02 -0400 Subject: [PATCH] fix(gridfs-stream): ensure `close` is emitted after last chunk NODE-1969 --- lib/gridfs-stream/download.js | 17 +++++++++---- test/functional/gridfs_stream_tests.js | 35 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/lib/gridfs-stream/download.js b/lib/gridfs-stream/download.js index 4583a943ed..dfb1de57f6 100644 --- a/lib/gridfs-stream/download.js +++ b/lib/gridfs-stream/download.js @@ -185,12 +185,19 @@ function doRead(_this) { } if (!doc) { _this.push(null); - return _this.s.cursor.close(function(error) { - if (error) { - return __handleError(_this, error); - } - _this.emit('close'); + + process.nextTick(() => { + _this.s.cursor.close(function(error) { + if (error) { + __handleError(_this, error); + return; + } + + _this.emit('close'); + }); }); + + return; } var bytesRemaining = _this.s.file.length - _this.s.bytesRead; diff --git a/test/functional/gridfs_stream_tests.js b/test/functional/gridfs_stream_tests.js index 45c8bcc4e7..f5811f76d8 100644 --- a/test/functional/gridfs_stream_tests.js +++ b/test/functional/gridfs_stream_tests.js @@ -420,6 +420,41 @@ describe('GridFS Stream', function() { } }); + it('should emit close after all chunks are received', { + metadata: { requires: { topology: ['single'] } }, + + test: function(done) { + const configuration = this.configuration; + const GridFSBucket = configuration.require.GridFSBucket; + + const client = configuration.newClient(configuration.writeConcernMax(), { poolSize: 1 }); + client.connect((err, client) => { + expect(err).to.not.exist; + const db = client.db(configuration.db); + const bucket = new GridFSBucket(db, { + bucketName: 'gridfsdownload', + chunkSizeBytes: 6000 + }); + + const readStream = fs.createReadStream('./LICENSE.md'); + const uploadStream = bucket.openUploadStream('teststart.dat'); + uploadStream.once('finish', function() { + const downloadStream = bucket.openDownloadStreamByName('teststart.dat'); + + const events = []; + downloadStream.on('data', () => events.push('data')); + downloadStream.on('close', () => events.push('close')); + downloadStream.on('end', () => { + expect(events).to.eql(['data', 'data', 'close']); + client.close(done); + }); + }); + + readStream.pipe(uploadStream); + }); + } + }); + /** * Deleting a file from GridFS *