Rails, threads and Facebook

Rails is not thread safe framework. That means Rails will process one request at a time. If there is more HTTP client requests they need to wait.

Of course there are some ways to make whole app more responsive. Basically You need to increase Rails instances number and provide some load balancing. mongrel_cluster will do :) but there are other issues.

Even if performance (or rather response time) is not issue, You need to remember that some calls to external APIs could suffer with single Rails app (like those run on webrick). Facebook API has method called FBML.refreshRefUrl to fetch some data from You app and serve it to Facebook’s users directly, from FB’s cache. Calling fbsession.FBML_refreshRefUrl will instantly trigger HTTP GET to Your app (assuming You are refreshing URL from own app, which is probably the case). From my observations Facebook needs this response to finish FBML.refreshRefUrl and get URL properly cached. With single Rails instance, it won’t happen – Webrick will queue HTTP GET from Facebook until RFacebook finish (timeout) call to FBML.refreshRefUrl.

From Yours (as developer) perspective URL won’t be refreshed in fb:ref calls.

There are some other dangers

Opening sockets to third party servers from Rails is potential issue. If there are some troubles making process longer (network congestion) it will freeze particular instance for whole connection setup. And believe me, it could sometimes take long seconds.

Let’s take following example. You have written some web app, which could interact with Facebook, but this is only add-on, main operations are made directly on Your’s application web interface. If application calls directly Facebook API in almost every action (using fbsesison when based on RFacebook) and there is connectivity problem, or performance issues on Facebook, Rails instance will be on hold until RFacebook::FacebookSession#call_method will time out. This could deplete Rails instances pool very fast and make Your application unresponsive to users.

So consider delegating all such tasks (communicating with Facebook API) to separate process and connect to it via DRb, then send request and don’t wait for results. Of course it makes sense only if this API is not crucial to provide Your service. If You are developing Facebook application, accessible only via Facebook web interface (in_canvas) You don’t have worry about that issue – in such setup any connectivity problem means big troubles for Your application.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.