Showing posts with label heroku. Show all posts
Showing posts with label heroku. Show all posts

Thursday, March 15, 2012

Make scheduled jobs in heroku safer for your wallet.

I recently checked my current usage on Heroku to find that I had used a much higher than expected number of dyno-hours. The project CheckTheSock.com is a RC aviation website that provides some weather data. The forecast data is pulled every hour via FTP by a rake task that is run with a scheduled job in Heroku. Normally this takes around a minute to run and uses about 13 or 14 dyno-hours in a month. Less than half way through this month I found that it had already burned through over 200 dyno-hours.

After digging into the problem I found that the FTP connection was hanging for some reason. After a little research I came up with a solution that works pretty nicely and for more than just hanging FTP connections.

It turns out that ruby's standard library includes a library named Timeout which provides a way to terminate the execution of a thread. Using this library it is very simple to set a time limit for a block of code in a rake test.

task :task_that_takes_a_long_time_sometimes do
  Timeout.timeout(30) do
    #The code that takes a long time to run sometimes
  end
end

That will raise a Timeout::Error if the code takes longer than 30 seconds to run. The error will cause the rake task to exit, preventing unexpected dyno-hour usage.

Wednesday, February 29, 2012

Rails A/B testing with Split on Heroku

I recently decided to start doing some A/B testing on www.checkthesock.com. The last time I tried A/B testing I used Google website optimizer, it worked fairly well but I did not like how difficult it was to setup a test. This time I looked around for A/B testing tools for rails. I ended up finding split and so far I have been very happy with the results. The documentation is fairly good but it did take a little fiddling to get it working on Heroku.

First off add the Redis to Go add-on in Heroku, the Nano plan is free and has been sufficient for my needs so far. Install redis on the dev server. I use a mac so that was as simple as "brew install redis" and then I followed the brew instructions for getting redis to start on login.

To install the split gem add the following to the Gemfile

 gem 'split', '0.3.3', :require => 'split/dashboard'

To set the development environment up in a way that is compatible to how Redis to Go is configured on Heroku add the following to config/environments/development.rb

ENV['REDISTOGO_URL'] = 'redis://localhost:6379'
Then create an initializer for redis in config/initializers/redis.rb and put the following in that file.
uri = URI.parse(ENV['REDISTOGO_URL'])
REDIS = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password, :username => uri.user)
To configure split to use the applications redis configuration create config/initializers/split.rb and add the following.
Split.redis = REDIS

To setup the split dashboard add the following to config/routes.rb

mount Split::Dashboard, :at => 'split'
To add authentication to the dashboard add the following to config/initializers/split.rb
Split::Dashboard.use Rack::Auth::Basic do |username, password|
  username == 'username' && password == 'password'
end

Setting up an A/B test is super easy just follow the instructions in the split README.

Resources:

Note: These instructions are for rails 3.x, the listed resources do have instructions for earlier versions of rails.