3

My students struggle a bit with ActiveRecord for Sinatra and Rails, but they eventually get it.

However, they completely burn out on Sequelize for Node.

To my mind, the biggest difference between Sequelize and AR is that AR is synchronous, whereas Sequelize is not.

Consider:

# ActiveRecord
@post = Post.find(2)
render json: @post

// Sequelize
Post.findById(2).then(function(post){
  response.json(post);
});

For small actions like this, the difference is still visible but it doesn't look so bad. With more complicated queries, it's easy to find yourself in callback hell.

So my question is: Why is it OK for ActiveRecord to be synchronous, but bad for a JS ORM to be synchronous?

I understand the disadvantages of synchronous vs. asynchronous. But the disadvantages of synchronicity don't really seem to be hurting ActiveRecord.

The difficulty with Sequelize isn't just that you have to write .then(function(){}) a thousand times; it's also that understanding how callbacks work at all takes a good amount of comfort with Javascript, and since Sequelize is the primary relational ORM for Node, it makes Node much less approachable to beginners. One might say "beginners shouldn't be using Node," but Rails has achieved a tremendous amount of success due to endeavors to make it approachable to novice developers.

RobertAKARobin
  • 3,933
  • 3
  • 24
  • 46
  • 1
    a little oversimplicity but...: synchronous means blocking, asynchronous is not blocking. When AR is waiting for data from DB it is blocking, sinatra cannot handle next request, in node while waiting requests are handle continuously . – kwarunek Nov 28 '15 at 21:33

1 Answers1

7

It is bad for a JS ORM to be synchronous, because the underlying execution engine (Node.js) is based on an asynchronous event loop based execution model.

The single reason why Node.js scales well, despite being single threaded, is because it uses non-blocking IO and has an active ecosystem of libraries that work well with the non-blocking asynchronous model.

It is exactly because of this, unlike ruby application servers, where a single process is processing just one request at a time, A node.js process can easily juggle a large number of requests as expensive IO operations (like reading from disk, reading from DB, communicating with external services) do not block the process.

In other words, if Node was synchronous then one user's database query would cause the server to "hang" and be unresponsive for all other users until the query completed.

Traditional threaded model Node Event loop

This post elaborates more on the details of the Node.js Event loop.

Now while this is intutive for web developers who have always dealt with callbacks in javascript, it does make things difficult for new developers, who are typically not familiar with callback oriented APIs. However, a few new advancements in Node.js are making things simpler.

Particularly noteworthy are support for generators and async/await functions. Using these features we can eliminate the callback pyramids and use normal try/catch syntax for error handling in asynchronous code as well.

Using a generator based control flow library like co asynchronous code can be written in a linear fashion, taking advantage of generators (which latest Node.js release already supports).

While async/await is not officially available in Node.js yet, it simplifies asynchronous code even further, eliminating the need for libraries like co. Using a transpiler like babel this feature can be used right now - and this is what I would recommend you to consider using in your class.

RobertAKARobin
  • 3,933
  • 3
  • 24
  • 46
lorefnon
  • 12,875
  • 6
  • 61
  • 93
  • Thanks for your response! I appreciate that Node scales well, and the advantages of being non-blocking. However, Rails seems to also scale well despite using AR: consider Coinbase.com and AirBnB, which both use Rails despite having considerably complicated database needs. I suppose my question is more, "Do the advantages of non-blocking SQL queries really outweigh the disadvantages in terms of code complexity?" – RobertAKARobin Nov 28 '15 at 21:42
  • I didn't realize that Node was single-threaded. That explains a lot! http://stackoverflow.com/questions/17959663/why-is-node-js-single-threaded – RobertAKARobin Nov 28 '15 at 21:51
  • 1
    I have updated the answer to explain scalability repurcussions, and strategies for reducing the code complexity. – lorefnon Nov 28 '15 at 22:00
  • Scalability of system is impacted by multiple aspects other than complexity of database model. In particular, more IO bound tasks benefit more from an Event loop based model. For use cases like Real time games, chat systems, trading systems, Node.js is a much more viable choice than Rails. – lorefnon Nov 28 '15 at 22:03