Permalink
Browse files

Support a callback in RedisReconnect middleware so we can use it on a…

… per-job basis.
  • Loading branch information...
1 parent cf3f2d5 commit 5151e3319d806627ffb315d8c3e721ec616711a5 @myronmarston myronmarston committed Mar 18, 2013
Showing with 54 additions and 11 deletions.
  1. +5 −3 lib/qless/middleware/redis_reconnect.rb
  2. +49 −8 spec/unit/middleware/redis_reconnect_spec.rb
@@ -1,14 +1,16 @@
module Qless
module Middleware
module RedisReconnect
- def self.new(*redis_connections)
+ def self.new(*redis_connections, &block)
Module.new do
define_singleton_method :to_s do
- "Qless::Middleware::RedisReconnect(#{redis_connections.map(&:id).join(', ')})"
+ "Qless::Middleware::RedisReconnect"
end
+ block ||= lambda { |job| redis_connections }
+
define_method :around_perform do |job|
- redis_connections.each do |redis|
+ Array(block.call(job)).each do |redis|
redis.client.reconnect
end
@@ -9,35 +9,76 @@ module Middleware
let(:url_1) { "redis://localhost:1234/2" }
let(:url_2) { "redis://localhost:4321/3" }
- it 'includes the redis connection strings in its description' do
+ it 'has a human readable description' do
redis_1 = Redis.new(url: url_1)
redis_2 = Redis.new(url: url_2)
middleware = Qless::Middleware::RedisReconnect.new(redis_1, redis_2)
- expect(middleware.inspect).to include(url_1, url_2)
- expect(middleware.to_s).to include(url_1, url_2)
+ expect(middleware.inspect).to include("Qless::Middleware::RedisReconnect")
+ expect(middleware.to_s).to include("Qless::Middleware::RedisReconnect")
end
- it 'reconnects to the given redis clients before performing the job' do
- events = []
-
+ def define_job_class(events)
stub_const("MyJob", Class.new {
define_singleton_method :perform do |job|
events << :performed
end
})
+ end
- redis_connections = 1.upto(2).map do |i|
+ def create_redis_connections(number, events)
+ number.times.map do |i|
client = fire_double("Redis::Client")
client.stub(:reconnect) { events << :"reconnect_#{i}" }
fire_double("Redis", client: client)
end
+ end
+
+ it 'reconnects to the given redis clients before performing the job' do
+ define_job_class(events = [])
+
+ redis_connections = create_redis_connections(2, events)
worker = Qless::Worker.new(stub)
worker.extend Qless::Middleware::RedisReconnect.new(*redis_connections)
worker.perform(Qless::Job.build(stub.as_null_object, MyJob))
- expect(events).to eq([:reconnect_1, :reconnect_2, :performed])
+ expect(events).to eq([:reconnect_0, :reconnect_1, :performed])
+ end
+
+ it 'allows the redis connections to be picked based on job data' do
+ define_job_class(events = [])
+ worker = Qless::Worker.new(stub)
+ redis_connections = create_redis_connections(4, events)
+
+ worker.extend Qless::Middleware::RedisReconnect.new { |job|
+ if job.data["type"] == "evens"
+ [redis_connections[0], redis_connections[2]]
+ else
+ [redis_connections[1], redis_connections[3]]
+ end
+ }
+
+ even_job = Qless::Job.build(stub.as_null_object, MyJob, data: { "type" => "evens" })
+ odd_job = Qless::Job.build(stub.as_null_object, MyJob, data: { "type" => "odds" })
+
+ worker.perform(even_job)
+ expect(events).to eq([:reconnect_0, :reconnect_2, :performed])
+
+ worker.perform(odd_job)
+ expect(events).to eq([:reconnect_0, :reconnect_2, :performed,
+ :reconnect_1, :reconnect_3, :performed])
+ end
+
+ it 'allows the block to return a single redis connection' do
+ define_job_class(events = [])
+ worker = Qless::Worker.new(stub)
+ redis_connections = create_redis_connections(1, events)
+
+ worker.extend Qless::Middleware::RedisReconnect.new { |job| redis_connections.first }
+ worker.perform(Qless::Job.build(stub.as_null_object, MyJob))
+
+ expect(events).to eq([:reconnect_0, :performed])
end
end
end

0 comments on commit 5151e33

Please sign in to comment.