Po zakończeniu prawidłowo zamknij połączenie mangusty


145

Używam mangusty w skrypcie, który nie powinien działać w sposób ciągły, i mam do czynienia z bardzo prostym problemem, ale nie mogę znaleźć odpowiedzi; po prostu mówiąc, kiedy wykonuję wywołanie dowolnej funkcji mongoose, która wysyła żądania do mongodb, moja instancja nodejs nigdy się nie zatrzymuje i muszę ją ręcznie zabić za pomocą, powiedzmy, Ctrl + c lub Program.exit ().

Kod wygląda mniej więcej tak:

var mongoose = require('mongoose');

// if my program ends after this line, it shuts down as expected, my guess is that the connection is not really done here but only on the first real request ?
mongoose.connect('mongodb://localhost:27017/somedb'); 

// define some models

// if I include this line for example, node never stop afterwards
var MyModel =  mongoose.model('MyModel', MySchema);

Próbowałem dodać wywołania do mongoose.disconnect (), ale nie otrzymałem wyniku. Poza tym wszystko działa dobrze (znajdowanie, zapisywanie, ...).

To jest dokładnie ten sam problem, co ta osoba, niestety nie otrzymał żadnej odpowiedzi: https://groups.google.com/group/mongoose-orm/browse_thread/thread/c72cc1c51c76e661

Dzięki

EDYCJA: zaakceptował poniższą odpowiedź, ponieważ jest technicznie poprawna, ale jeśli ktoś kiedykolwiek napotka ten problem ponownie, wydaje się, że mongoose i / lub sterownik mongodb w rzeczywistości nie zamykają połączenia, gdy pytasz, czy nadal są uruchomione zapytania.

W ogóle nie pamięta nawet połączenia rozłączającego, nie robi tego po zakończeniu wykonywania zapytań; po prostu odrzuca twoje wywołanie bez wyrzuconego wyjątku lub czegokolwiek w tym rodzaju i nigdy tak naprawdę nie zamyka połączenia.

Więc masz to: upewnij się, że każde zapytanie zostało przetworzone przed wywołaniem odłączenia (), jeśli chcesz, aby faktycznie działało.


1
Czy można to zrobić tylko poprzez zaimportowanie modelu? żadna z poniższych odpowiedzi nie działa: \
Anthony,

Odpowiedzi:


201

Możesz zamknąć połączenie za pomocą

mongoose.connection.close()

25
To faktycznie zamyka połączenie. Jednak to wezwanie wyczyściło zawartość mojej bazy danych. Kiedy przełączyłem się na mongoose.disconnect (), wszystko działało poprawnie, a moje testy mokki znów zaczęły działać poprawnie
Brian Noah

1
To zadziałało dla mnie. Musiałem się tylko upewnić, że umieściłem to we właściwym wywołaniu zwrotnym, w przeciwnym razie prawdopodobnie zamykało połączenie, zanim zapis do bazy danych miał szansę zakończyć. Aby być uczciwym, nadal używam prostego skryptu, który po prostu łączy się z lokalną bazą danych i zapisuje prosty przykładowy obiekt użytkownika. W wywołaniu zwrotnym do user.save () wywołuję mongoose.connection.close ().
FateNuller

6
Jak widać, te odpowiedzi są stare. Jeśli używasz Mongoose 5.0.4 , metoda jest eksportowana tylko, dostępny tylko, więc z niego korzystać. Connection.close()
Константин Ван

74

Druga odpowiedź mi nie pomogła. Musiałem użyć, mongoose.disconnect();jak podano w tej odpowiedzi .


Jest to również preferowane podczas niszczenia środowiska testowego.
Matt Lo

1
mongoose.disconnect () jest lepsza w użyciu i jest logicznym podejściem.
Abdul Alim Shakir,

17

Możesz ustawić połączenie na zmienną, a następnie rozłączyć je, gdy skończysz:

var db = mongoose.connect('mongodb://localhost:27017/somedb');

// Do some stuff

db.disconnect();

W mojej sytuacji (testowanie Mongoose w Jest) to jedyne rozwiązanie, które zadziałało
Code Whisperer

Robię Model.update (..) z Mongoose w pętli for. Czy konieczne jest zamykanie połączenia po każdej aktualizacji? Mój serwer musi obsłużyć wiele aktualizacji i po pewnym czasie przestał działać.
Pille

Ta sama odpowiedź jak poniżej
Daniel W.

3

Używam wersji 4.4.2 i żadna z pozostałych odpowiedzi nie zadziałała. Ale dodanie useMongoClientdo opcji i umieszczenie jej w zmiennej, do której się odwołujesz, closewydawało się działać.

var db = mongoose.connect('mongodb://localhost:27017/somedb', { useMongoClient: true })

//do stuff

db.close()

1

Jeśli spróbujesz zamknąć / rozłączyć się poza tą metodą, pojawi się błąd. Najlepszym rozwiązaniem jest zamknięcie połączenia w obu callbackach w metodzie. Fikcyjny kod jest tutaj.

const newTodo = new Todo({text:'cook dinner'});

newTodo.save().then((docs) => {
  console.log('todo saved',docs);
  mongoose.connection.close();
},(e) => {
  console.log('unable to save');
});

1

Tak jak powiedział Jake Wilson: Możesz ustawić połączenie na zmienną, a następnie rozłączyć je, gdy skończysz:

let db;
mongoose.connect('mongodb://localhost:27017/somedb').then((dbConnection)=>{
    db = dbConnection;
    afterwards();
});


function afterwards(){

    //do stuff

    db.disconnect();
}

lub jeśli w funkcji Async:

(async ()=>{
    const db = await mongoose.connect('mongodb://localhost:27017/somedb', { useMongoClient: 
                  true })

    //do stuff

    db.disconnect()
})

w przeciwnym razie, gdy sprawdzałem go w swoim środowisku, wystąpił błąd.


0

Prawdopodobnie masz to:

const db = mongoose.connect('mongodb://localhost:27017/db');

// Do some stuff

db.disconnect();

ale możesz też mieć coś takiego:

mongoose.connect('mongodb://localhost:27017/db');

const model = mongoose.model('Model', ModelSchema);

model.find().then(doc => {
  console.log(doc);
}

nie możesz zadzwonić, db.disconnect()ale po użyciu możesz zamknąć połączenie.

model.find().then(doc => {
  console.log(doc);
}).then(() => {
  mongoose.connection.close();
});
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.