Resque
Resque is a queueing system that is backed by Redis. Common use cases include sending emails and processing data. For more information about Resque itself, visit http://github.com/defunkt/resque. This tutorial will cover setting up Resque with Rails and Redis To Go.
Set Up Rails
This is going to be a Rails 3 app, so get the latest gem.
$ sudo gem install rails --pre
Create the application:
$ rails new cookie_monster
$ cd cookie_monster
Modify the Gemfile to include Resque.
source 'http://rubygems.org'
gem 'rails', '3.0.0.rc'
gem 'sqlite3-ruby', :require => 'sqlite3'
gem 'resque'
Install all of the gems and dependencies using Bundler.
$ bundle install
Set Up Redis To Go
Go to Redis To Go and sign up for the free plan. Once
you have an instance, grab the URL given to you and modify the
config/initializers/resque.rb
as follows:
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, :thread_safe => true)
Create a Job
Jobs are Ruby classes or modules that respond to the perform
method. A good
place to put jobs that perform background work would be in app/jobs
. Create
the job named Consume
in app/jobs/eat.rb
module Eat
@queue = :food
def perform(food)
puts "Ate #{food}!"
end
end
Inside config/initializers/resque.rb
place the following code so that
app/jobs/eat.rb
is loaded.
Dir["/app/app/jobs/*.rb"].each { |file| require file }
Enqueue the Job
The main use case for using a queuing system is to take prevent a task that
could take more than a second from blocking a request. This will often happen
in either the model or controller. Create a controller named eat
.
$ rails g controller eat
Create a route for the controller in config/routes.rb
CookieMonster::Application.routes.draw do
match 'eat/:food' => 'eat#food'
end
Create the action in the controller. This action will put a job on the queue and return the request, leaving any work to be done outside of the request.
class EatController < ApplicationController
def food
Resque.enqueue(Eat, params[:food])
render :plain => "Put in fridge to eat later."
end
end
Start a Worker
Open lib/tasks/resque.rake
and place the following inside.
require 'resque/tasks'
task "resque:setup" => :environment
This will load the Resque tasks and load the environment which is required for doing any work.
To start a worker that will pull work off of all queues run the command:
$ rake resque:work QUEUE=*
Start the Server
In a separate terminal start the rails server.
$ rails s
Test the Application
Pull up a browser and go to http://localhost:3000/eat/cookie
. You should get
the following response.
Put cookie in fridge to eat later.
In the terminal where you started the worker it should have outputted:
Ate cookie!
Introspection
One of the most useful aspects of Resque is the ability to perform
introspection. Resque has a great interface that can be give you and
understanding of what is going on. The best part is that you can load it in a
subpath with Rack's URLMap
.
Open config.ru
and replace what is in the file with the following code. This
will boot your app as the root and give you /resque
as the web front end to
Resque.
require ::File.expand_path('../config/environment', __FILE__)
require 'resque/server'
run Rack::URLMap.new \
"/" => CookieMonster::Application,
"/resque" => Resque::Server.new
From /resque
you can see what is in your queues, the workers and what they
are currently doing, and the ability to view any failed jobs.
Deploy to Heroku
This part can be done two different ways, using the Heroku Redis To Go add-on or signing up for directly.
The only adjustment that we need to make is to map the rake task jobs:work
to resque:work
and set the queues to watch. After making these changes the
Heroku workers will work wonderfully. Open lib/tasks/resque.rake
and replace
what is in there with the following:
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"
Now create the Heroku app and deploy.
$ git init
$ git ci -am "Initial Commit."
$ heroku create
$ heroku addons:add redistogo
$ git push heroku master
Now if you got to the /eat/cookie
a job will be placed on the Resque
queue. You can view the queue from /resque
Conclusion
This should get you up and running with Resque and on your way to a scalable solution. If you run into any issues please don't hesitate to reach out to us at support@redistogo.com!