mirror of
https://github.com/mperham/sidekiq.git
synced 2022-11-09 13:52:34 -05:00
Explicitly pass Redis associated with this job
When pushing a job, the middleware should be able to access the Redis instance associated with that job. Previously, Sidekiq was limited to one global Redis instance. Now that we want to support sharding, we have to explicitly pass the instance in OR hack up APIs with thread local variables. Explicit is better.
This commit is contained in:
parent
dd798bb6be
commit
83aea0690e
8 changed files with 19 additions and 26 deletions
|
@ -40,6 +40,8 @@ end
|
|||
client = Sidekiq::Client.new(ConnectionPool.new { Redis.new })
|
||||
client.push(...)
|
||||
```
|
||||
**Sharding support does require a breaking change to client-side
|
||||
middleware, see Upgrading.md.**
|
||||
- New Chinese, Greek, Swedish and Czech translations for the Web UI.
|
||||
- Updated most languages translations for the new UI features.
|
||||
- **Remove official Capistrano integration** - this integration has been
|
||||
|
|
|
@ -6,6 +6,15 @@ changes a few data elements in Redis. To upgrade cleanly:
|
|||
* Upgrade to the latest Sidekiq 2.x and run it for a few weeks.
|
||||
`gem 'sidekiq', '< 3'`
|
||||
This is only needed if you have retries pending.
|
||||
* 3rd party gems which use **client-side middleware** will need to update
|
||||
due to an API change. The Redis connection for a particular job is
|
||||
passed thru the middleware to handle sharding where jobs can
|
||||
be pushed to different redis server instances.
|
||||
|
||||
`def call(worker_class, msg, queue, redis_pool)`
|
||||
|
||||
Client-side middleware should use `redis_pool.with { |conn| ... }` to
|
||||
perform Redis operations and **not** `Sidekiq.redis`.
|
||||
* If you used the capistrano integration, you'll need to pull in the
|
||||
new [capistrano-sidekiq](https://github.com/seuros/capistrano-sidekiq)
|
||||
gem and use it in your deploy.rb.
|
||||
|
|
|
@ -54,15 +54,12 @@ module Sidekiq
|
|||
# push('queue' => 'my_queue', 'class' => MyWorker, 'args' => ['foo', 1, :bat => 'bar'])
|
||||
#
|
||||
def push(item)
|
||||
Thread.current[:current_pool] = @redis_pool
|
||||
normed = normalize_item(item)
|
||||
payload = process_single(item['class'], normed)
|
||||
|
||||
pushed = false
|
||||
pushed = raw_push([payload]) if payload
|
||||
pushed ? payload['jid'] : nil
|
||||
ensure
|
||||
Thread.current[:current_pool] = nil
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -80,7 +77,6 @@ module Sidekiq
|
|||
# pushed can be less than the number given if the middleware stopped processing for one
|
||||
# or more jobs.
|
||||
def push_bulk(items)
|
||||
Thread.current[:current_pool] = @redis_pool
|
||||
normed = normalize_item(items)
|
||||
payloads = items['args'].map do |args|
|
||||
raise ArgumentError, "Bulk arguments must be an Array of Arrays: [[1], [2]]" if !args.is_a?(Array)
|
||||
|
@ -90,25 +86,10 @@ module Sidekiq
|
|||
pushed = false
|
||||
pushed = raw_push(payloads) if !payloads.empty?
|
||||
pushed ? payloads.collect { |payload| payload['jid'] } : nil
|
||||
ensure
|
||||
Thread.current[:current_pool] = nil
|
||||
end
|
||||
|
||||
class << self
|
||||
|
||||
#
|
||||
# Returns the Redis pool being used for the current client operation.
|
||||
# Client operations should use +Sidekiq::Client.redis_pool+ whereas server
|
||||
# operations should use +Sidekiq.redis_pool+.
|
||||
#
|
||||
# For example, in client-side middleware, you must use this method.
|
||||
# In server-side middleware, you use +Sidekiq.redis_pool+.
|
||||
#
|
||||
# This complexity is necessary to support Redis sharding.
|
||||
def redis_pool
|
||||
Thread.current[:current_pool] || Sidekiq.redis_pool
|
||||
end
|
||||
|
||||
def default
|
||||
@default ||= new
|
||||
end
|
||||
|
@ -187,7 +168,7 @@ module Sidekiq
|
|||
def process_single(worker_class, item)
|
||||
queue = item['queue']
|
||||
|
||||
middleware.invoke(worker_class, item, queue) do
|
||||
middleware.invoke(worker_class, item, queue, @redis_pool) do
|
||||
item
|
||||
end
|
||||
end
|
||||
|
|
|
@ -54,7 +54,7 @@ module Sidekiq
|
|||
# to Redis:
|
||||
#
|
||||
# class MyClientHook
|
||||
# def call(worker_class, msg, queue)
|
||||
# def call(worker_class, msg, queue, redis_pool)
|
||||
# puts "Before push"
|
||||
# result = yield
|
||||
# puts "After push"
|
||||
|
|
|
@ -2,7 +2,7 @@ module Sidekiq::Middleware::I18n
|
|||
# Get the current locale and store it in the message
|
||||
# to be sent to Sidekiq.
|
||||
class Client
|
||||
def call(worker_class, msg, queue)
|
||||
def call(worker_class, msg, queue, redis_pool)
|
||||
msg['locale'] ||= I18n.locale
|
||||
yield
|
||||
end
|
||||
|
|
|
@ -61,7 +61,7 @@ class TestClient < Sidekiq::Test
|
|||
it 'allows local middleware modification' do
|
||||
@redis.expect :lpush, 1, ['queue:default', Array]
|
||||
$called = false
|
||||
mware = Class.new { def call(worker_klass,msg,q); $called = true; msg;end }
|
||||
mware = Class.new { def call(worker_klass,msg,q,r); $called = true; msg;end }
|
||||
client = Sidekiq::Client.new
|
||||
client.middleware do |chain|
|
||||
chain.add mware
|
||||
|
@ -200,7 +200,8 @@ class TestClient < Sidekiq::Test
|
|||
describe 'client middleware' do
|
||||
|
||||
class Stopper
|
||||
def call(worker_class, message, queue)
|
||||
def call(worker_class, message, queue, r)
|
||||
raise ArgumentError unless r
|
||||
yield if message['args'].first.odd?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -120,7 +120,7 @@ class TestMiddleware < Sidekiq::Test
|
|||
I18n.locale = 'fr'
|
||||
msg = {}
|
||||
mw = Sidekiq::Middleware::I18n::Client.new
|
||||
mw.call(nil, msg, nil) { }
|
||||
mw.call(nil, msg, nil, nil) { }
|
||||
assert_equal :fr, msg['locale']
|
||||
|
||||
msg['locale'] = 'jp'
|
||||
|
|
|
@ -28,7 +28,7 @@ class TestScheduled < Sidekiq::Test
|
|||
end
|
||||
|
||||
class Stopper
|
||||
def call(worker_class, message, queue)
|
||||
def call(worker_class, message, queue, r)
|
||||
yield if message['args'].first.odd?
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue