简体   繁体   中英

Mongodb Tailable Cursor in nodejs, how to stop stream

I use below code to get the data from mongodb capped collection

function listen(conditions, callback) {

        db.openConnectionsNew( [req.session.client_config.db] , function(err, conn){

            if(err) {console.log({err:err}); return next(err);}

            coll = db.opened[db_name].collection('messages');

        latestCursor = coll.find(conditions).sort({$natural: -1}).limit(1)
        latestCursor.nextObject(function(err, latest) {
            if (latest) {
                conditions._id = {$gt: latest._id}
            }
            options = {
                tailable: true,
                awaitdata: true,
                numberOfRetries: -1
            }
            stream = coll.find(conditions, options).sort({$natural: -1}).stream()
            stream.on('data', callback)
        });

        });
    }

and then I use sockets.broadcast(roomName,'data',document);

on client side

io.socket.get('/get_messages/', function(resp){
});
io.socket.on('data', function notificationReceivedFromServer ( data ) {
  console.log(data);

});

this works perfectly as I am able to see the any new document which is inserted in db.

I can see in mongod -verbose that after each 200ms there is query running with the query {$gt:latest_id} and this is fine, but I have no idea how can i close this query :( I am very new in nodejs and using the mongodb tailable option for the first time and am totally lost, any help or clue is highly appreciated

What is returned from the .stream() method from the Cursor object returned from .find() is an implementation of the node transform stream interface. Specifically this is a "readable" stream.

As such, it's "data" event is emitted whenever there is new data received and available in the stream to be read.

There are other methods such as .pause() and .resume() which can be used to control the flow of these events. Typically you would call these "inside" a "data" event callback, where you wanted to make sure the code in that callback was executed before the "next" data event was processed:

stream.on("data", function(data) {
   // pause before processing
   stream.pause();

  // do some work, possibly with a callback
  something(function(err,result) {

      // Then resume when done
      stream.resume();
  });
});

But of course this is just a matter of "scoping". So as long as the "stream" variable is defined in a scope where another piece of code can access it, then you can call either method at any time.

Again, by the same token of scoping, you can just "undefine" the "stream" object at any point in the code, making the "event processing" redundant.

// Just overwrite the object
scope = undefined;

So worth knowing. In fact the newer "version 2.x" of the node driver wraps a "stream interface" directly into the standard Cursor object without the need to call .stream() to convert. Node streams are very useful and powerful things that it would be well worth while coming to terms with their usage.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM