Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Long-polling in Rails apps

I have an app that has a page on which user must see in relatively real-time how 2 steps are processed.

Now this is done by ajax short-polling. I'd like to change it to some less server-heavy technique and I'm choosing between Faye gem and ajax long-polling.
Ajax long-polling is easier to implement and doesn't require any server intrusions. It will take 4 ajax requests (for page to be informed on 2 steps completion).
Faye gem will take 3 requests sent, which is not a lot less. And it will require me to set up my nginx-passenger server and is harder to implement and support in general.

I would choose ajax long-polling, but I heard that it will require a whole Rails instance running while request is long-polled, which will exhaust my RAM. On the other hand from this How rails server on production works? I understand that Rails may not have this problem with long-polling. So, what is true, - will ajax long-polling from multiple clients require many concurrent applications processing (which may overallocate some of my resources, not sure which)?

like image 772
lakesare Avatar asked Aug 29 '15 12:08

lakesare


1 Answers

You question raises the possibility of three different techniques:

  • Websockets (Faye, Iodine, EM-Websockets or whatever websocket solution you prefer).
  • Short-polling (client based 'pull' style notifications).
  • Long-polling (client and server attempt at a persistent connection - pre websockets technology).

Although Websockets seem to be the most scalable and natural solution for push notifications, it is - as most things are - an application specific question. You will need to consider your resources and your demands and balance them the best way you can.

Websockets vs. Short-polling each carry a "price". While Short-Polling is easier to implement, Websockets allow for real "push" and their design is meant to conserve web and server resources.

As for Websockets vs. Long polling, the answer is quite simple - Websockets will be more efficient.

Long polling emulates a persistent connection by blocking the HTTP request sent by the browser until the server has data to "answer" with. This could block the whole server if it's concurrency isn't effective and it would obviously block the thread in charge of answering the request (how many threads are in your server's thread pool? 8? 24?).

In contrast, Websockets ARE persistent connections which don't block, but integrate with the server. It's a much more elegant and resource friendly solution.

You can find more information about long polling vs. short polling here:

  • Short-polling vs Long-polling for real time web applications?

  • Scaling a chat app - short polling vs. long polling (AJAX, PHP)

In example:

Let's assume you expect 5,000 active clients connected to your website any given moment (if each client spends 30 minutes a day connected, this assumes ~ 240K clients in total, disregarding peaks and ebbs is usage times).

Now, let us compare resources just for the push/update part of the application:

  • Short Polling: If each client sends an update query every 2 seconds (not fast, but not too slow, depending what you need), you need to handle 2,500 requests/second only to answer the update query requests. Each request will impact the memory, performance and responsiveness of your app.

  • Long Polling: You will have 5000 connections blocked and waiting for a response. That's 5,000 tasks which probably use up a thread each... even if you manage to cycle the tasks using some async-response and a thread pool (which is super difficult with Rack servers), you will be eating up CPU and memory waiting for updates. Also, each update will require you to renew the 5,000 connections (or, if you're lucky, HTTP/1.1's keep-alive feature will save you from this inconvenience). These blocked connections will effect the responsiveness and performance of your app, using CPU cycles and taking focus from real requests. It might (or might not) be better than attempting to answer 2,500 requests per second... but not very effective. Pushing data is immediate.

  • Websockets: You will have 5,000 connections added to the server's IO reactor. The websocket callbacks will be called whenever there is any activity (which might never happen) and none of your threads are blocked. Updates sent using websocket connections don't cause the connections to close, so there is no need to renew the connections with every update. Pushing data is immediate.

to conclude:

By design, if you have your own server, you should be able to serve many more clients using Websockets than using Short or Long polling.

However:

  1. Websockets (as well as long-polling) are harder to code than short-polling (they use a very valuable resource which is human coding hours);

  2. some hosting services (i.e. Heroku) will limit the websocket clients count, making the "math" less certain... on the other hand, concurrency limits (req/sec) for these same services would probably end up in favor of websockets.

like image 115
Myst Avatar answered Sep 18 '22 01:09

Myst