Skip to content

Commit

Permalink
http_resque 0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
philc committed Mar 20, 2012
0 parents commit fc74059
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
@@ -0,0 +1,4 @@
*.gem
.bundle
Gemfile.lock
pkg/*
4 changes: 4 additions & 0 deletions Gemfile
@@ -0,0 +1,4 @@
source "http://rubygems.org"

# Specify your gem's dependencies in http_resque.gemspec
gemspec
3 changes: 3 additions & 0 deletions README.markdown
@@ -0,0 +1,3 @@
HTTP Resque
===========
Docs forthcoming.
1 change: 1 addition & 0 deletions Rakefile
@@ -0,0 +1 @@
require "bundler/gem_tasks"
83 changes: 83 additions & 0 deletions bin/http_resque
@@ -0,0 +1,83 @@
#!/usr/bin/env ruby

# This wraps the Resque process with a thin HTTP API which enables you to manipulate jobs using HTTP requests
# and run jobs synchronously, off-box, for the purposes of integration testing background jobs. This is
# necessary because background jobs fail notoriously often in production and so they need integration -- not
# unit -- tests. This helps you to cleanly write those integration tests.
#
# Usage:
# QUEUE=* http_resque -p 8080
# The server uses port 4567 by default. Use -p to specify an alternate port.
# You'll note that the QUEUE environment variable is used just like it is when running `rake resque:work`.

# Once it's started, you can access these URLs to manipulate jobs:
# GET /queues/:queue/jobs
# DELETE /queues/:queue/jobs
# POST /queues/:queue/jobs
# GET /queues/:queue/result_of_oldest_job

require "sinatra/base"
require "thin"
require "resque"
require "rake"
require "json"

# Load the Rakefile which should in turn require all of their Resque job classes.
# TODO(philc): The path to this Rakefile should be an argument.
load "./Rakefile"

class HttpResque < Sinatra::Base
settings.server = "thin"

STDOUT.sync = STDERR.sync = true

# Run rake resque:work in a background process. It will exit when this process exits.
fork { Rake::Task["resque:work"].invoke }

settings.port = ARGV.include?("-p") ? ARGV[ARGV.index("-p") + 1] : ENV["PORT"]

get "/" do
"http_resque is here."
end

# The Resque representation of up to 25 jobs in this queue, *oldest* first. Resque jobs look like this:
# { "class"=>"DeployBuild", "args"=>["my_embed_code", "my_youtube_synd_id"] }
get "/queues/:queue/jobs" do
(Resque.peek(params[:queue], 0, 25) || []).to_json
end

delete "/queues/:queue/jobs" do
Resque.remove_queue(params[:queue])
nil
end

# Create a new job.
# - queue: the queue to enqueue this job into.
# - arguments: optional; an array of arguments for the Resque job.
post "/queues/:queue/jobs" do
halt(400, "Provide a valid JSON body.") unless json_body
klass = json_body["class"]
halt(400, "Specify a class.") unless klass
klass = Object.const_get(klass)
Resque.enqueue_to(params[:queue], klass, *json_body["arguments"])
nil
end

# Executes the job at the head of this queue (the oldest job), and blocks until it's finished.
# This is useful for scripting integration tests which verify that a background job is working correctly.
get "/queues/:queue/result_of_oldest_job" do
job = Resque::Job.reserve(params[:queue])
halt(404, "No jobs left in #{params[:queue]}") unless job
begin
job.perform
rescue => error
halt(500, "This job raised an exception when run: " +
"#{job.inspect}\n#{error.class}: #{error.message}\n#{error.backtrace.join("\n")}")
end
nil
end

def json_body() @json_body ||= JSON.parse(request.body.read) rescue nil end

run! if app_file == $0
end
25 changes: 25 additions & 0 deletions http_resque.gemspec
@@ -0,0 +1,25 @@
# -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)
require "http_resque/version"

Gem::Specification.new do |s|
s.name = "http_resque"
s.version = HttpResque::VERSION
s.authors = ["Phil Crosby"]
s.email = ["phil.crosby@gmail.com"]
s.homepage = "http://github.com/philc/http_resque"
s.summary = "A small HTTP wrapper around Resque, so you can schedule and test jobs over HTTP."

s.rubyforge_project = "http_resque"

s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]

s.add_runtime_dependency "thin"
s.add_runtime_dependency "resque"
s.add_runtime_dependency "rake"
s.add_runtime_dependency "json"
s.add_runtime_dependency "sinatra"
end
1 change: 1 addition & 0 deletions lib/http_resque.rb
@@ -0,0 +1 @@
require "howdy/version"
3 changes: 3 additions & 0 deletions lib/http_resque/version.rb
@@ -0,0 +1,3 @@
module HttpResque
VERSION = "0.0.1"
end

0 comments on commit fc74059

Please sign in to comment.