UPD:
Na podstawie tego posta wygląda na to, że wdrożyli poprawkę, która zrobi to samo, co my tutaj. Nie jestem pewien, czy jest to już w npm (15.10.13). https://github.com/mongodb/node -mongodb-native/issues/1092#ref-commit-2667d13
Po pewnym dochodzeniu udało mi się zrozumieć, co się tam dzieje:
Za każdym razem, gdy wywołujesz jakąkolwiek metodę obsługi bazy danych (znajdowanie, aktualizowanie, wstawianie itp.) tworzy ona kursor, który ma własne ID i sam się rejestruje do EventEmitter firmy Db w celu późniejszego wywołania. W międzyczasie rejestruje się w obiekcie _notReplied w ramach tego samego CallBackStore.
Ale po zamknięciu połączenia nie mogłem zlokalizować niczego, co przeszłoby przez kursory _notReplied i wywołałoby je z błędami lub jakąkolwiek logiką z zegarami (nadal może gdzieś tam być). Udało mi się więc napisać małe obejście, które wymusza wyzwalanie kursorów z błędem, gdy DB emituje close
wydarzenie:
new mongodb.Db('testdb', new mongodb.Server('localhost', 27017, { }), { safe: true }).open(function (err, db) {
if (!err) {
db.on('close', function() {
if (this._callBackStore) {
for(var key in this._callBackStore._notReplied) {
this._callHandler(key, null, 'Connection Closed!');
}
}
});
// ...
} else {
console.log(err)
}
});
Polecam pierwsze podejście zamiast MongoClient. Powodów jest kilka:na przykład, gdy zamykasz połączenie, a następnie wywołujesz .find
poprawnie wywoła błąd w wywołaniu zwrotnym, podczas gdy w przypadku MongoClient tak się nie stanie.
Jeśli używasz MongoClient:
MongoClient.connect('mongodb://localhost:27017/testdb', function(err, db) {
if (!err) {
db.on('close', function() {
if (this._callBackStore) {
for(var key in this._callBackStore._notReplied) {
this._callHandler(key, null, 'Connection Closed!');
}
}
});
// ...
} else {
console.log(err);
}
});
Co to zrobi? Po zamknięciu połączenia będzie iterować przez wszystkie kursory _notReplied i wyzwalać dla nich zdarzenia z błędem Connection Closed!
.
Przypadek testowy:
items.find({ }).toArray(function(err, data) {
if (!err) {
console.log('Items found successfully');
} else {
console.log(err);
}
});
db.close();
To wymusi zamknięcie połączenia z bazą danych i wywoła close
zdarzenie, które obsługujesz wcześniej i upewnisz się, że kursor zostanie zamknięty.
UPD:Dodałem problem na GitHub:https://github.com /mongodb/node-mongodb-native/issues/1092 zobaczymy, co powiedzą na ten temat.