Node.js / Mongoose / MongoDB: los zócalos de bashs de conexión iniciales fallidos todavía están activos en segundo plano

Aunque esta pregunta se hizo hace más de un año, sigue siendo relevante para mí. También estoy tratando de proporcionar más información para hacer que esto no sea solo un duplicado. Como se indicó en la pregunta original: si se conecta a una base de datos MongoDB con Mongoose y la conexión falla, se devuelve la llamada con un error, pero todo el bash de conexión todavía se está ejecutando en segundo plano (y no se está cerrando) y su secuencia de comandos no termina

Así que este ejemplo …

var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/database', function(err) { if (err) { console.log("error"); mongoose.disconnect(); // Obviously does nothing, because mongoose.connection.readyState prevents any action. return; } console.log("success"); mongoose.disconnect(); }); 

… imprime “éxito” y finaliza si el servidor MongoDB ya se está ejecutando antes de que esto se ejecute e imprima “error” y sigue funcionando para siempre si el servidor MongoDB no está disponible desde el principio. Aquí está la salida de la consola del servidor MongoDB con una ejecución exitosa del código anterior ( poolSize = 5 ) con un aspecto correcto hasta el momento:

 2016-01-07T04:15:24.385+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58873 #1 (1 connection now open) 2016-01-07T04:15:24.385+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58874 #2 (2 connections now open) 2016-01-07T04:15:24.385+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58875 #3 (3 connections now open) 2016-01-07T04:15:24.386+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58876 #4 (4 connections now open) 2016-01-07T04:15:24.386+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58877 #5 (5 connections now open) 2016-01-07T04:15:24.403+0100 I NETWORK [conn1] end connection 127.0.0.1:58873 (4 connections now open) 2016-01-07T04:15:24.403+0100 I NETWORK [conn2] end connection 127.0.0.1:58874 (3 connections now open) 2016-01-07T04:15:24.403+0100 I NETWORK [conn3] end connection 127.0.0.1:58875 (2 connections now open) 2016-01-07T04:15:24.404+0100 I NETWORK [conn4] end connection 127.0.0.1:58876 (1 connection now open) 2016-01-07T04:15:24.404+0100 I NETWORK [conn5] end connection 127.0.0.1:58877 (0 connections now open) 

Ahora, lo que hace que este problema “sin terminación por error” sea un problema es que los bashs de conexión aún están activos de alguna manera, incluso si se llama a la callback con, por ejemplo, un error ECONNREFUSED . Y eso me está causando problemas.

Debido al hecho de que el manejo automático de la reconexión de Mongoose no se realiza en la primera conexión (fallida), quería escribir mi propia secuencia de comandos “esperar al servidor MongoDB si no se está ejecutando actualmente” como se muestra aquí .

Mi version:

 var mongoose = require('mongoose'); function connect() { mongoose.connect('mongodb://localhost/database', function(err) { if (err) { console.log("error"); mongoose.disconnect(); setTimeout(connect, 5000); return; } console.log("success"); mongoose.disconnect(); }); } connect(); 

Lo que sucede es que cada vez que se llama al método de connect(...) , se crean un montón de nuevas conexiones con el servidor MongoDB. Y a pesar de que la callback se llamó con un error, estos bashs de conexión aún están activos. Puedo verificar esto iniciando el servidor MongoDB después de, por ejemplo, el primer bash fallido de conexión y lo que obtendré en el registro después de 5 segundos es lo siguiente:

 2016-01-07T04:23:07.501+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58893 #1 (1 connection now open) 2016-01-07T04:23:07.501+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58894 #2 (2 connections now open) 2016-01-07T04:23:07.503+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58895 #3 (3 connections now open) 2016-01-07T04:23:07.503+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58896 #4 (4 connections now open) 2016-01-07T04:23:07.504+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58897 #5 (5 connections now open) 2016-01-07T04:23:09.499+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58898 #6 (6 connections now open) 2016-01-07T04:23:09.500+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58899 #7 (7 connections now open) 2016-01-07T04:23:09.501+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58900 #8 (8 connections now open) 2016-01-07T04:23:09.503+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58901 #9 (9 connections now open) 2016-01-07T04:23:09.503+0100 I NETWORK [initandlisten] connection accepted from 127.0.0.1:58902 #10 (10 connections now open) 2016-01-07T04:23:09.515+0100 I NETWORK [conn6] end connection 127.0.0.1:58898 (9 connections now open) 2016-01-07T04:23:09.516+0100 I NETWORK [conn7] end connection 127.0.0.1:58899 (8 connections now open) 2016-01-07T04:23:09.516+0100 I NETWORK [conn8] end connection 127.0.0.1:58900 (7 connections now open) 2016-01-07T04:23:09.516+0100 I NETWORK [conn9] end connection 127.0.0.1:58901 (6 connections now open) 2016-01-07T04:23:09.517+0100 I NETWORK [conn10] end connection 127.0.0.1:58902 (5 connections now open) 

Y también como puede ver, solo las conexiones exitosas se desconectan con la llamada mongoose.disconnect() después de registrar el “éxito” en la consola. Creo que esto es especialmente un problema porque si el servidor MongoDB no se inicia dentro de los 5 segundos posteriores a la secuencia de comandos pero, por ejemplo, con un retraso de unos minutos, el número máximo de conexiones posibles podría superarse con las conexiones semiabiertas / desconocidas / zombis. Y debido al hecho de que mi script debería estar ejecutándose durante algunos días, tener algunas conexiones de zombis al azar con vida durante días no debería considerarse aceptable.

¿Se trata de un error en Mongoose, el controlador nativo de MongoDB o estoy haciendo algo mal?

EDITAR:

Profundicé aún más en este problema y descubrí que este (ver 1. más abajo) es el lugar en mongodb-core / MongoDB Core Driver donde se crean las conexiones / sockets a MongoDB. Agregué salidas de depuración aquí (ver 2) y aquí (ver 3) de esta manera:

  1. github.com/christkv/mongodb-core/blob/master/lib/connection/connection.js
  2. github.com/christkv/mongodb-core/blob/master/lib/connection/connection.js#L140
  3. github.com/christkv/mongodb-core/blob/master/lib/connection/connection.js#L376

(Lo sentimos, solo puedo publicar 2 enlaces con mi reputación siendo )

 // ... [L138] var closeHandler = function(self) { console.log("socket: close"); // <-- return function(hadError) { // ... [L141] // ... [L374] self.connection.on('connect', function() { console.log("socket: connect"); // <-- // Set socket timeout instead of connection timeout self.connection.setTimeout(self.socketTimeout); // ... [L378] 

En el caso de una conexión exitosa de la secuencia de comandos de ejemplo anterior, esperaba que se conectaran 5 sockets, así que pensé en la siguiente salida (esperada):

 socket: connect socket: connect socket: connect socket: connect socket: connect success 

Lo que obtuve fue:

 socket: close socket: close socket: close socket: close socket: close socket: connect socket: connect socket: connect socket: connect socket: connect success 

¿Por qué los sockets emiten eventos close antes de que se conecten correctamente en contexto con el controlador MongoDB / las bibliotecas / módulos de mongoose?

Porque si hago lo siguiente (el servidor MongoDB ya se está ejecutando) …

 var net = require('net'); var socket = net.createConnection(27017, 'localhost'); socket.on('close', function() { console.log("socket: close"); }); socket.on('connect', function() { console.log("socket: connect"); }); 

… el registro satisface mis expectativas:

 socket: connect 

Sé que es una pregunta muy larga. Ya aprecio si lees hasta aquí / el final.

    Intereting Posts