MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Gestion des délais d'attente avec Node.js et mongodb

UPD :
Sur la base de ce message, il semble qu'ils aient déployé un correctif qui fera la même chose que ce que nous faisons ici. Je ne sais pas si c'est déjà dans npm (15.10.13). https://github.com/mongodb/node -mongodb-native/issues/1092#ref-commit-2667d13

Après quelques recherches, j'ai réussi à comprendre ce qui s'y passe :
Chaque fois que vous appelez une méthode pour gérer la base de données (recherche, mise à jour, insertion, etc.), elle crée un curseur, qui a son propre ID et s'enregistre lui-même à EventEmitter de Db pour être rappelé plus tard. En attendant, il s'enregistre auprès de l'objet _notReplied dans le même CallBackStore.

Mais une fois la connexion fermée, je ne pouvais pas localiser quoi que ce soit qui itérerait à travers les curseurs _notReplied et les déclencherait avec des erreurs ou toute logique avec des minuteries (il pourrait toujours être quelque part là-bas). J'ai donc réussi à écrire un petit travail autour, qui force les déclencheurs de curseurs avec erreur lorsque DB émet close événement :

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

Je recommande d'utiliser la première approche au lieu de MongoClient. Les raisons sont peu nombreuses :par exemple lorsque vous fermez la connexion, puis appelez .find il déclenchera correctement une erreur de rappel, alors qu'avec MongoClient, ce ne sera pas le cas.

Si vous utilisez 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'est-ce que cela va faire? Une fois la connexion fermée, elle parcourra tous les curseurs _notReplied et déclenchera des événements pour eux avec l'erreur Connection Closed! .

Scénario de test :

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

Cela forcera la fermeture de la connexion à la base de données et déclenchera close événement que vous gérez plus tôt et s'assurera que le curseur sera fermé.

UPD :J'ai ajouté le problème sur GitHub :https://github.com /mongodb/node-mongodb-native/issues/1092 nous verrons ce qu'ils disent à ce sujet.