I’d rather Go complain about Rails

[SPOILER ALERT]

Actually this is not a complaint. I don’t root for any particular technology. It’s just I found Go outperforming Rails in this particular use case.

[END OF SPOILER]

I’ve had this post in the queue for a while but never managed to finish it. Part of the reason for this is due to what I’m going to tell you with the sequel of this post.

I’m writing this post to share my experience but also request for comments. I might really have misunderstood something in the process so I want to hear back from you.

I had this little notification service that mostly did this:

  1. accept an HTTP connection
  2. setup a thread listening on a channel over Redis
  3. setup a thread that pings the client to know for premature disconnects
  4. join the 2 threads with the current one and wait for a notification from the Redis channel

My Rails controller was pretty much like the following:

This controller was simply keeping the incoming connection open as long as new notification records were ready to be dispatched to the client. The begin, rescue, ensure dance was there to handle the case of premature client disconnects. Prematurely closing clients were keeping the controller in use until the timeout was reached. But I needed to save resources and be able to release them as soon as the client disconnected. I found it pretty hard in Rails to hook the client disconnection and it looks like it’s pretty much implementation-dependent and varies from server to server.

Anyway, this worked pretty nicely. As long as there were no more than ~4 connected clients. :/

More than ~4 connected clients made my nginx+passenger freeze. No way I could figure it out. I didn’t manage to fix that. Also, I wasn’t sure how many MySQL connection Rails was using. Connections to the database were being open and never closed until server restart.

So, given I had pretty nice results with similar services in the past with Go, I decided to spend the night and port the notifications controller to a tiny Go-based (Martini-helped) web service.

Here’s the result (actually a lighter version of it).

I feel this version of the service more consistent. Also, the language provides me with the means to discover when the client disconnects. And even the Redis library this time helps me understand when un-subscription occurs.

This, of course, will be compiled and turned into a native server that only handles the notification system. As a result, this outperforms the Rails-based version of the service. I found it pretty stable also. This service has then been proxied through Nginx and has never crashed since then (~5 months). I don’t serve much clients actually, ~30-40 simultaneous connections, but this amount wasn’t sustainable with Rails. Also, the MySQL connections were open and closed as expected and the number of simultaneous connections was reasonable.

I’d like your feedback regarding this experience. I know Go would always outperform Ruby in cases like this but I’m interested in understanding what was wrong with my Rails implementation. Also, can you confirm detecting client disconnect is pretty hard with Rails (4.2) ?

Cheers everybody.

One Reply to “I’d rather Go complain about Rails”

  1. Do you mind if I quote a few of your posts as long as I provide credit and sources back
    to your website? My blog site is in the exact same niche as yours and my users would definitely benefit from some of
    the information you provide here. Please let me know if this ok with you.
    Appreciate it!

Leave a Reply

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

Are you a robot? *