Async patterns with node and mongoose

148 views
Skip to first unread message

Joshua Abrams

unread,
Apr 1, 2014, 11:09:31 PM4/1/14
to mongoo...@googlegroups.com

Specifically I'm working with Mongoose and Node, but I guess this is a more conceptual question about asynchronous coding.

I see this example all over Mongoose docs:

product.sold = Date.now();
product.save(function (err, product, numberAffected) {
  if (err) ..
})

However, what if

product.save(...) 

executes faster than

product.sold = Date.now()

Wouldn't you be saving before updating...? Maybe I'm missing something here (at a conceptual level)? What's keeping this code "safe" in an asynchronous environment.

More specifically I'm using doc.addToSet as the "update" step, and I'd feel much better if it had a callback I could embed the doc.save step in (to ensure async behavior). Thoughts?

PS. I'm not simply using model.update because I need validation.

Joe Wagner

unread,
Apr 2, 2014, 12:13:31 AM4/2/14
to mongoo...@googlegroups.com
The thing to keep in mind is that with Node and Mongoose is that code that doesn't do any IO is synchronous.  In your example, 
product.sold = Date.now();
always finishes executing before product.save(...) runs, but product.save does IO so it finishes executing and registers a callback to be executed when the IO returns, which happens asynchonously.

doc.addToSet is also synchronous, so you are "safe" to use it before doc.save

Joshua Abrams

unread,
Apr 2, 2014, 2:07:10 AM4/2/14
to mongoo...@googlegroups.com
Thanks for the response Joe. It's starting to become clearer. A follow up question. Is there an alternative to doc.addToSet that's async rather than sync? I don't want to block the event loop. I know model.update is async (and could do the same thing) but it does't provide validation.

Joe Wagner

unread,
Apr 2, 2014, 12:05:03 PM4/2/14
to mongoo...@googlegroups.com
addToSet doesn't save anything to the database, its similar to Array.push so you don't have to worry about blocking the event loop.  There are only a few functions that hit the disk and work synchronously.  For example fs.writeFileSync will block the event loop, but fs.writeFile will not.

The benifit to node's async behaviour is that IO or anything that goes over the network takes orders of magnitude more walltime than operations like addToSet.  This means the machine running your code doesn't have to wait for mongo to confirm saving to disk before accepting more requests, or whatever it wants to do next.

Here's an interesting though experiment:
If you are using, for example, the php mongo driver, and you set the db's write concern to 0.  your updates don't block because there is no need to wait for mongo to confirm the success of the write operation.

Hope that helps

On Tuesday, April 1, 2014 9:09:31 PM UTC-6, Joshua Abrams wrote:

Joshua Abrams

unread,
Apr 3, 2014, 4:16:07 AM4/3/14
to mongoo...@googlegroups.com
Helps a ton. Makes total sense. Thanks Joe.
Reply all
Reply to author
Forward
0 new messages