sql >> Base de Datos >  >> NoSQL >> MongoDB

Manejo de tiempos de espera con Node.js y mongodb

UPD:
Según esta publicación, parece que implementaron una solución que hará lo mismo que hacemos aquí. No estoy seguro si esto ya está dentro de npm (15.10.13). https://github.com/mongodb/node -mongodb-native/issues/1092#ref-commit-2667d13

Después de investigar un poco, logré entender lo que está pasando allí:
Cada vez que llamas a cualquier método para tratar con la base de datos (buscar, actualizar, insertar, etc.), crea un cursor, que tiene su propia ID y se registra a sí mismo a EventEmitter de Db para que le devuelvan la llamada más tarde. Mientras tanto, se registra en el objeto _notReplied dentro del mismo CallBackStore.

Pero una vez que se cerró la conexión, no pude ubicar nada que iteraría a través de los cursores _notReplied y los activaría con errores o cualquier lógica con temporizadores (todavía podría estar en algún lugar allí). Así que me las arreglé para escribir un pequeño trabajo, eso obliga a activar los cursores con error cuando DB emite close evento:

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)
  }
});

Recomiendo usar el primer enfoque en lugar de MongoClient. Las razones son pocas:por ejemplo, cuando cierra la conexión y luego llama a .find activará correctamente el error en la devolución de llamada, mientras que con MongoClient no lo hará.

Si está utilizando 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);
  }
});

¿Qué hará esto? Una vez que se cierra la conexión, iterará a través de todos los cursores _notReplied y desencadenará eventos para ellos con el error Connection Closed! .

Caso de prueba:

items.find({ }).toArray(function(err, data) {
  if (!err) {
    console.log('Items found successfully');
  } else {
    console.log(err);
  }
});
db.close();

Eso forzará el cierre de la conexión de la base de datos y activará close evento que manejó anteriormente y se asegurará de que el cursor se cierre.

UPD:he agregado un problema en GitHub:https://github.com /mongodb/node-mongodb-native/issues/1092 veremos que dicen al respecto.