New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to properly handle watcher errors/disconnection #14312
Comments
This issue is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 5 days |
After analyzing the problem a little more closely, I realized several things:
So, simply call the ".watch(...)" method when the "error" event is emitted, but ignore the others in order to keep watchers open.
|
Based on our investigation from #14419, 'close' is the event to listen for. In Node.js streams, 'close' means the stream is closed and no more events should be emitted. We did find a minor issue where the MongoDB Node driver emits duplicate 'close' events, but when we run the following script it looks like there's no more non-'close' events emitted after 'close' if you stop and restart the underlying replica set: 'use strict';
const mongoose = require('mongoose');
void async function main() {
const uri = 'mongodb://127.0.0.1:27017,127.0.0.1:27018/mongoose_test';
await mongoose.connect(uri);
const Person = mongoose.model('Person', mongoose.Schema({ name: String }));
await Person.createCollection();
let resumeAfter = null;
let changeStream = await Person.watch();
addChangeStreamListeners(changeStream);
function addChangeStreamListeners(changeStream) {
changeStream.on('change', data => console.log(new Date(), data));
changeStream.on('resumeTokenChanged', data => {
console.log(new Date(), 'resumeTokenChanged', data);
resumeAfter = data;
});
changeStream.on('error', data => console.log(new Date(), 'error', data));
changeStream.on('close', data => {
console.log(new Date(), 'close', data, new Error().stack);
//changeStream = Person.watch([], { resumeAfter });
//addChangeStreamListeners(changeStream);
});
}
while (true) {
await new Promise(resolve => setTimeout(resolve, 8000));
// Insert a doc, will trigger the change stream handler above
console.log(new Date(), 'Inserting doc');
await Person.create({ name: 'Axl Rose' });
console.log(new Date(), 'Inserted doc');
}
}(); Why not emit the "end" event when the stream is finished and no reconnection is made?: Node.js stream API doesn't specify an 'end' event. There's a 'finish' event, but that's when Why not propose, via the options of the ".watch(...)" method, an automatic reconnection even in the event of an error? We're planning on implementing that in #14419 |
Prerequisites
Mongoose version
8.0.3
Node.js version
20.10.0
MongoDB version
6.0.13 (atlas server) & 6.2.0 (node)
Operating system
Linux
Operating system version (i.e. 20.04, 11.3, 10)
Debian Bullseye 11
Issue
Hello, for some time now, some of my watchers have been disconnecting and not reconnecting, resulting in events not being received. I'm unable to reproduce the problem effectively locally, but once in production it often happens:
Here is my current code :
--> How can I efficiently detect when watchers are completely closed in order to restart it ?
N.B. I've tried listening for the "close" event but sometimes it's sent but events are always received and sometimes afterwards there are no more events received.
The text was updated successfully, but these errors were encountered: