Heroku_redis_example is a project mainly written in RUBY and JAVASCRIPT, based on the MIT license.
Example Rails Heroku cloud-app that uses Resque with Redis
This is an extremely basic Ruby on Rails Application that demonstrates how a Rails 2.3 application hosted on Heroku can use Resque with Redis.
Adapted from Resque with Redis To Go by James R. Bracy and Defunkt's Resque
The main difference is that this application runs on Rails 2.3x rather than Rails 3 and this application has no database dependency. Mr. Bracy has a Rails 3.x version of this example.
rails heroku_redis_example
cd heroku_redis_example
environment.rb
: config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
rm RAILS_ROOT/config/database.yml
Create and add this to Gemfile
source 'http://rubygems.org'
gem "rails", ">=2.3.8" gem 'resque' gem 'SystemTimer'
bundle install
bundle lock
Add a preinitializer file to work around Bundler issues: (From: http://stackoverflow.com/questions/2170697/bundler-isnt-loading-gems)
begin
require File.expand_path('../.bundle/environment', __FILE__)
rescue LoadError
require "rubygems"
require "bundler"
Bundler.setup
end
Bundler.require
create RAILS_ROOT/config/resque.rb
and add:
ENV["REDISTOGO_URL"] ||= "redis://username:password@host:1234/"
uri = URI.parse(ENV["REDISTOGO_URL"]) Resque.redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
Dir["#{Rails.root}/app/jobs/*.rb"].each { |file| require file }
Create RAILS_ROOT/config.ru
require "config/environment" require 'resque/server' require 'logger'
use Rails::Rack::LogTailer use Rails::Rack::Static use Rack::ShowExceptions
AUTH_PASSWORD = 'secret' if AUTH_PASSWORD Resque::Server.use Rack::Auth::Basic do |username, password| password == AUTH_PASSWORD end end
run Rack::URLMap.new "/" => ActionController::Dispatcher.new, "/resque" => Resque::Server.new
Create a job in app/jobs/trogdor.rb
class Trogdor @queue = :terrorize
def self.perform(target)
puts "Burninating the #{target}!"
end
end
In this step we write the code that will be initiated by a web request and itself initiate a worker.
RAILS_ROOT/script/generate controller trogdor
Create this method in the controller:
def burninate Resque.enqueue(Trogdor, params[:target]) render :text => "Telling Trogdor to burninate #{params[:target]}." end
Here we tell Rails how to handle a certain web request in order to invoke the burninate
method in TrogdorController
Set RAILS_ROOT/config/routes.rb
to:
ActionController::Routing::Routes.draw do |map| map.trogdor 'trogdor/burninate/:target', :controller => 'trogdor', :action => 'burninate' end
In lib/tasks/resque.rake
:
require 'resque/tasks'
task "resque:setup" => :environment do ENV['QUEUE'] = '*' end
desc "Alias for resque:work (To run workers on Heroku)" task "jobs:work" => "resque:work"
git init
git add .
git commit -m 'Initial commit'
heroku create
heroku addons:add redistogo
git push heroku master
Verify Resque-web works:
Verify the application works:
Kickoff the worker using Heroku rake command syntax:
heroku rake resque:work --app young-sunrise-78 --trace
Observe the output of the console command to heroku rake:
~/heroku_redis_example(master) $ heroku rake resque:work --app young-sunrise-78 --trace (in /disk1/home/slugs/258287_149fab6_faff/mnt) Invoke resque:work (first_time) Invoke resque:setup (first_time) Invoke environment (first_time) Execute environment Execute resque:setup Execute resque:work Burninating the countryside!
Now, let's imagine you have heroku rake
running but you'd like to extend or correct some aspect
of your Job. In order to do this you need to clear out the Job environment on Heroku.
^C
(Control C) to escape your heroku rake
taskheroku rake resque:work
again. This new rake call will then load up the new code you just deployed. Otherwise, it would be using old code and not reflect your changes/improvements.
Once you are happy with your application and your background jobs it's time to bite the bullet
and start worker jobs in Heroku officially. Simply starting workers manually with heroku rake
is
insufficient as this will create workers only for as long as it takes for Heroku to timeout.
To create a long-running Heroku worker:
~/heroku_redis_example(master) $ heroku workers 1 --app young-sunrise-78
This action will cause your account to be billed at the end of the month
For more information, see http://docs.heroku.com/billing
Are you sure you want to do this? (y/n) y
young-sunrise-78 now running 1 worker