Using Ruby’s timout to keep the user experience snappy

On a my Ruby on Rails based San Francisco Sailing Weather website I make calls out to flickr.rb to retrieve photos.

It’s not a key feature but I like it and to keep the code simple I fetch the photos from the controller and pass them to the view (as opposed to a batch job in the background). I use a fragment cache that expires every 30 minutes to avoid hitting flickr on every page view which keeps the code simple, easy to read, and the pages generally load fast.

However, once in a while the flickr API can get slow and if you’re the unlucky user to hit the site when it’s slow AND the photos aren’t cached the page could take a long time to load. I ended up using a Ruby timout to solve the problem and just bail on fetching photos if the flickr API takes longer than 5 seconds:

@photos = []
begin
  unless cached?({:part => "flickr_photos"}, 30.minutes)
    timeout(5.seconds) do
      @photos = flickr_photos
    end
  end
rescue Timeout::Error
  logger.error('Exception: ' + $!)
end

Now if the flickr_photos method takes more than 5 seconds an exception is thrown and logged (so I can measure how often it occurs) and the view then display the box with a “photos are currently offline” message.

This entry was posted in Ruby on Rails, Software Engineering, Web. Bookmark the permalink.