Redis To Go

Simple Redis Hosting

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 :text => "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!