Permalink
Browse files

Workers started with QUEUE=* do not cause error when there are no queues

* This should rarely happen (if at all) in production, but in
  development, we ran into annoying situations if Redis were cleared and
  we tried to start a catch-all Resque worker (via Foreman).
* The worker that is started will not process jobs, but at least it will
  not die immediately with a bad exit code (which would stop all
  processes in Foreman, for instance).
  • Loading branch information...
1 parent 99c7c78 commit 1ca67f1e858b4751404e426ea038079f8895c2ca @alindeman committed Jun 6, 2012
Showing with 31 additions and 10 deletions.
  1. +18 −9 lib/resque/multi_queue.rb
  2. +13 −1 test/multi_queue_test.rb
@@ -46,11 +46,15 @@ def pop(non_block = false)
end
else
queue_names = @queues.map {|queue| queue.redis_name }
- synchronize do
- value = @redis.blpop(*(queue_names + [1])) until value
- queue_name, payload = value
+ if queue_names.any?
+ synchronize do
+ value = @redis.blpop(*(queue_names + [1])) until value
+ queue_name, payload = value
queue = @queue_hash["#{@redis.namespace}:#{queue_name}"]
- [queue, queue.decode(payload)]
+ [queue, queue.decode(payload)]
+ end
+ else
+ Kernel.sleep # forever
end
end
end
@@ -61,12 +65,17 @@ def pop(non_block = false)
# the timeout expires.
def poll(timeout)
queue_names = @queues.map {|queue| queue.redis_name }
- queue_name, payload = @redis.blpop(*(queue_names + [timeout]))
- return unless payload
+ if queue_names.any?
+ queue_name, payload = @redis.blpop(*(queue_names + [timeout]))
+ return unless payload
- synchronize do
- queue = @queue_hash["#{@redis.namespace}:#{queue_name}"]
- [queue, queue.decode(payload)]
+ synchronize do
+ queue = @queue_hash["#{@redis.namespace}:#{queue_name}"]
+ [queue, queue.decode(payload)]
+ end
+ else
+ Kernel.sleep(timeout)
+ nil
end
end
end
@@ -1,6 +1,6 @@
require "test_helper"
-describe "Resque::MulitQueue" do
+describe "Resque::MultiQueue" do
let(:redis) { Resque.redis }
let(:coder) { Resque::MultiJsonCoder.new }
@@ -15,6 +15,11 @@
assert_nil queue.poll(1)
end
+ it "poll is a no-op when queues are empty" do
+ queue = Resque::MultiQueue.new([], redis)
+ assert_nil queue.poll(1)
+ end
+
it "blocks on pop" do
foo = Resque::Queue.new 'foo', redis, coder
bar = Resque::Queue.new 'bar', redis, coder
@@ -92,4 +97,11 @@
assert_equal processed_queues, queues
end
+
+ it "blocking pop is a no-op if queues are empty" do
+ queue = Resque::MultiQueue.new([], redis)
+ assert_raises Timeout::Error do
+ Timeout.timeout(2) { queue.pop }
+ end
+ end
end

0 comments on commit 1ca67f1

Please sign in to comment.