Created
September 11, 2009 23:27
-
-
Save rcarver/185656 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Job | |
extend self | |
def low(klass, *args) | |
queue.enqueue(:low, klass, *args) | |
end | |
def high(klass, *args) | |
queue.enqueue(:high, klass, *args) | |
end | |
def live_queue? | |
Merb.env =~ /production/ | |
end | |
def queue | |
@queue ||= live_queue? ? Resque : MemoryQueue.new | |
end | |
class MemoryQueue | |
def initialize | |
@jobs = [] | |
@job_results = [] | |
end | |
attr_reader :job_results, :jobs_performed | |
def clear! | |
@jobs = [] | |
@job_results = [] | |
@jobs_performed = [] | |
end | |
def enqueue(queue, klass, *args) | |
@jobs << [queue, klass, args] | |
end | |
def results_of(klass, queue=nil) | |
results = job_matches(klass, queue) | |
raise "#{klass} was run multiple times" if results.any? && results.size > 1 | |
results.first | |
end | |
def has_performed?(klass, queue=nil) | |
job_matches(klass, queue).any? | |
end | |
def perform_all | |
@job_results = [] | |
@jobs_performed = [] | |
@jobs.each do |queue, klass, args| | |
results = klass.perform(*args) | |
@job_results << results | |
@jobs_performed << [klass, queue, results] | |
end | |
@jobs = [] | |
end | |
def job_matches(klass, queue=nil) | |
@jobs_performed.collect do |job_klass, job_queue, results| | |
if queue | |
results if queue == job_queue && klass == job_klass | |
else | |
results if klass == job_klass | |
end | |
end.compact | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb') | |
describe "The job queue" do | |
module TestJob | |
def self.perform(name) | |
"#{name} was run" | |
end | |
end | |
class JobQueueingController < Application | |
def queue_no_jobs | |
render "ok" | |
end | |
def queue_one_job | |
Job.low TestJob, "from queue_one_job" | |
render "ok" | |
end | |
def queue_two_jobs | |
Job.low TestJob, "one from queue_two_jobs" | |
Job.high TestJob, "two from queue_two_jobs" | |
render "ok" | |
end | |
end | |
before(:all) do | |
@old_routes = Merb::Router.routes | |
Merb::Router.prepare(@old_routes) do | |
to(:controller => "job_queueing_controller") do | |
match('/none').to(:action => "queue_no_jobs") | |
match('/one').to(:action => "queue_one_job") | |
match('/two').to(:action => "queue_two_jobs") | |
end | |
end | |
end | |
after(:all) do | |
Merb::Router.prepare(@old_routes) { } | |
end | |
it "is run after every request" do | |
lambda { request("/one") }.should change(Job.queue, :job_results).from([]).to(["from queue_one_job was run"]) | |
Job.queue.should have_performed(TestJob) | |
Job.queue.should have_performed(TestJob, :low) | |
Job.queue.should_not have_performed(TestJob, :high) | |
Job.queue.results_of(TestJob).should == "from queue_one_job was run" | |
Job.queue.results_of(TestJob, :low).should == "from queue_one_job was run" | |
Job.queue.results_of(TestJob, :high).should be_nil | |
end | |
it "is cleared after every request" do | |
lambda { request("/one") }.should change(Job.queue, :job_results).from([]).to(["from queue_one_job was run"]) | |
lambda { request("/none") }.should change(Job.queue, :job_results).from(["from queue_one_job was run"]).to([]) | |
Job.queue.should_not have_performed(TestJob) | |
Job.queue.results_of(TestJob).should be_nil | |
end | |
it "runs all queued jobs" do | |
lambda { request("/two") }.should change(Job.queue, :job_results).from([]).to(["one from queue_two_jobs was run", "two from queue_two_jobs was run"]) | |
Job.queue.should have_performed(TestJob) | |
Job.queue.should have_performed(TestJob, :low) | |
Job.queue.should have_performed(TestJob, :high) | |
lambda { Job.queue.results_of(TestJob) }.should raise_error("#{TestJob} was run multiple times") | |
Job.queue.results_of(TestJob, :low).should == "one from queue_two_jobs was run" | |
Job.queue.results_of(TestJob, :high).should == "two from queue_two_jobs was run" | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Application < Merb::Controller | |
protected | |
after :run_job_queue_unless_live_queue | |
def run_job_queue_unless_live_queue | |
Job.queue.perform_all unless Job.live_queue? | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment