Skip to content

Commit

Permalink
fix(cursor): close underlying query cursor when calling destroy()
Browse files Browse the repository at this point in the history
Fix #14966
  • Loading branch information
vkarpov15 committed Oct 23, 2024
1 parent 925327f commit 1a2fd2b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
21 changes: 21 additions & 0 deletions lib/cursor/queryCursor.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,27 @@ QueryCursor.prototype.close = async function close() {
}
};

/**
* Marks this cursor as destroyed. Will stop streaming and subsequent calls to
* `next()` will error.
*
* @return {this}
* @api private
* @method _destroy
*/

QueryCursor.prototype._destroy = function _destroy(_err, callback) {
this.cursor.close()
.then(() => {
this._closed = false;
callback();
})
.catch(error => {
callback(error);
});
return this;
};

/**
* Rewind this cursor to its uninitialized state. Any options that are present on the cursor will
* remain in effect. Iterating this cursor will cause new queries to be sent to the server, even
Expand Down
16 changes: 16 additions & 0 deletions test/query.cursor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

'use strict';

const { once } = require('events');
const start = require('./common');

const assert = require('assert');
Expand Down Expand Up @@ -920,6 +921,21 @@ describe('QueryCursor', function() {
assert.ok(cursor.cursor);
assert.equal(driverCursor, cursor.cursor);
});

it('handles destroy() (gh-14966)', async function() {
db.deleteModel(/Test/);
const TestModel = db.model('Test', mongoose.Schema({ name: String }));

const stream = await TestModel.find().cursor();
await once(stream, 'cursor');
assert.ok(!stream.cursor.closed);

stream.destroy();

await once(stream.cursor, 'close');
assert.ok(stream.destroyed);
assert.ok(stream.cursor.closed);
});
});

async function delay(ms) {
Expand Down
6 changes: 6 additions & 0 deletions types/cursor.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ declare module 'mongoose' {
*/
close(): Promise<void>;

/**
* Destroy this cursor, closing the underlying cursor. Will stop streaming
* and subsequent calls to `next()` will error.
*/
destroy(): this;

/**
* Rewind this cursor to its uninitialized state. Any options that are present on the cursor will
* remain in effect. Iterating this cursor will cause new queries to be sent to the server, even
Expand Down

0 comments on commit 1a2fd2b

Please sign in to comment.