Ary Borenszweig

Ary Borenszweig

Ary is a software craftsman, he is our guru in all code-related problems. Always teaching how to develop the best code with simplicity in mind, he makes everything seem easy no matter how difficult, to the point that nothing seems impossible with him on the team. Very optimistic (sometimes too much), he has the ability to put any idea into code in almost no time.

Avoiding ActiveRecord instance creation to boost performance

It is known that instantiating ActiveRecord objects is slow. When querying, most of the time it’s necessary to instantiate them so we can invoke their methods or navigate their relationships.

When you need to do a custom select with a group by you generally do:

Model.select(...).group(...).all

This will create an ActiveRecord instance for each of the results, with accessors for each of the elements in the select clause. This is very expensive compared to just creating arrays of the values as the result of the query.

So let’s do it:

class ActiveRecord::Relation
  def raw
    connection.execute(to_sql)
  end
end

You can use it like this:

Model.select('id, sum(hours)').group('id').raw.each do |id, hours|
  # ...
end

Here’s a sample IRB session showing the performance gain:

irb(main):024:0> WorkedHour.where(work_group_id: 1).select('worker_id, worked_at, sum(hours)').group('worker_id, worked_at').all.length
=> 3369
irb(main):025:0> time = Time.now; WorkedHour.where(work_group_id: 1).select('worker_id, worked_at, sum(hours)').group('worker_id, worked_at').all; Time.now - time
=> 0.314908
irb(main):026:0> time = Time.now; WorkedHour.where(work_group_id: 1).select('worker_id, worked_at, sum(hours)').group('worker_id, worked_at').raw.to_a; Time.now - time
=> 0.044524
irb(main):027:0> 0.314908 / 0.044524
=> 7.072769742161531

So, creating arrays as results for 3369 objects instead of ActiveRecord objects results in a 7x performance boost.

Nuntium: exponential backoff and new xmpp library

This week we’ve updated nuntium to version 2.8, yay!

Aside from some minor bug fixes, nuntium now implements an exponential backoff strategy when a message delivery fails. Previously, it worked like this:

  1. A message failed to be delivered.
  2. If the cause was the message itself (for example it contains invalid data), it was discarded.
  3. If the cause was an authentication problem, for example an SMTP server’s password changed, the channel responsible for delivering the message was disabled and an alert was sent to the administrator.
  4. Otherwise, the cause was a temporary one, maybe a connection timeout. In that case, delivery through that channel was suspended for five minutes with an alert being sent to the administrator.

In this last point, sometimes the cause was in fact an invalid message for which the other side expecting to get the message wasn’t correctly prepared to handle. This caused all subsequent valid messages to be suspended for five minutes.

We changed this behavior to just suspend this message for some time (using an exponential backoff strategy) but allowing next messages to be sent. The message is marked as “delayed” an you can see it in the UI. We think this is a much more resilient solution.

The other big thing is that we changed the library we used to receive and send XMPP messages. Previously we used xmpp4r, which works quite well but sometimes it would raise unexpected exceptions which we couldn’t understand. Also, it wasn’t based on event machine. We switched to the excelent blather library and so far it didn’t let us down.

What’s next? Having implemented delayed messages on failure cases we are only a small step away from implementing delayed messages just for the sake of it. Imagine sending a message to nuntium and telling it to send it on a specific date. With this you could implement things as simple as birthday reminders to pregnancy checks reminders or messages sent today or tomorrow afternoon of a given time zone.

New office, ruby cake

Two weeks ago, Friday, was the last day in our old office. The mood was pretty nice since the new office has direct sun light and is much more comfortable, and also because every Friday, in a round-robin fashion, each one of us brings some delicious for dessert. It was my turn.

I’m not much of a cook. I checked some online recipes and finally settled on a Chocotorta, a somewhat famous pie here in Argentina that you can prepare with chocolate cookies, coffee, dulce de leche and white cheese. I wanted it to be special for this last day so I thought about decorating it with powder chocolate that would read either “Friday” or “Manas”. But those words were too long and they wouldn’t fit. So the closest thing that meant happiness to me but was shorter was “Ruby”. :-P

Here’s a picture of it. The “R” is not very clear…

The rubycake

The rubycake

So here’s the recipe I used:

Ingredients:

  • 3 packs of Chocolinas
  • 500 grams of dulce de leche
  • 300 grams of white cheese
  • 1 cup of hot chocolate milk (can also be coffee)
  • Chocolate powder
  • 1 pionono (can be replaced with chocolinas)
  • 1 peach

Mix the dulce the leche and the white cheese. I also added some chocolate powder to it. We’ll call this the stuffing.

Wet some chocolinas in the hot chocolate milk and with them form a rectangle, like a platform. Then put some of the stuffing on it. Then put either another platform of chocolinas or pionono. Continue until your formed three or four platforms. On top of the final platform put more sutffing. Sprinkle the chocolate powder to form the word “Ruby”. Chop the peach in tiny sliced and put them around. Don’t forget to put one slice in the “R”‘s hole and two on the “B”‘s circle. Put on the fridge. You are done!

rgviz-rails updated to Rails 3

I just updated the rgviz-rails gem to work with Rails 3. It was pretty easy, following the instructions of this site.

I also moved the code from Google Code to github, so i can have all my projects under a single tree, and to start using git more frequently.

Here are the new URLs:

http://github.com/asterite/rgviz
http://github.com/asterite/rgviz-rails