mirror of
https://github.com/mperham/sidekiq.git
synced 2022-11-09 13:52:34 -05:00
Adjust middleware, fixes #5371
Middleware now has access to the `config` object so we can provide local helper methods.
This commit is contained in:
parent
ab3c8ead5b
commit
d985aa35f0
8 changed files with 163 additions and 17 deletions
|
@ -5,11 +5,12 @@
|
||||||
6.5.0
|
6.5.0
|
||||||
---------
|
---------
|
||||||
|
|
||||||
- Substantial refactoring of Sidekiq server internals, as part of a larger effort to
|
- Substantial refactoring of Sidekiq server internals, part of a larger effort
|
||||||
reduce Sidekiq's internal usage of global methods and data, see [docs/component.md](docs/component.md) and [docs/global_to_local.md](docs/global_to_local.md).
|
to reduce Sidekiq's internal usage of global methods and data, see [docs/component.md](docs/component.md),
|
||||||
- Add **beta** support for the `redis-client` gem**. This will become the default Redis driver in Sidekiq 7.0. [#5298]
|
[docs/global_to_local.md](docs/global_to_local.md) and [docs/middleware.md](docs/middleware.md).
|
||||||
|
- **Add beta support for the `redis-client` gem**. This will become the default Redis driver in Sidekiq 7.0. [#5298]
|
||||||
Read more: https://github.com/mperham/sidekiq/wiki/Using-redis-client
|
Read more: https://github.com/mperham/sidekiq/wiki/Using-redis-client
|
||||||
- Add **beta** support for DB transaction-aware client [#5291]
|
- **Add beta support for DB transaction-aware client** [#5291]
|
||||||
Add this line to your initializer and any jobs created during a transaction
|
Add this line to your initializer and any jobs created during a transaction
|
||||||
will only be pushed to Redis **after the transaction commits**. You will need to add the
|
will only be pushed to Redis **after the transaction commits**. You will need to add the
|
||||||
`after_commit_everywhere` gem to your Gemfile.
|
`after_commit_everywhere` gem to your Gemfile.
|
||||||
|
|
87
docs/middleware.md
Normal file
87
docs/middleware.md
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
# Middleware Changes in Sidekiq 7.0
|
||||||
|
|
||||||
|
With the internal refactoring coming in Sidekiq 7.0 it is necessary
|
||||||
|
to make minor changes to the Middleware API.
|
||||||
|
|
||||||
|
> tl;dr - middleware should now include Sidekiq::ClientMiddleware or Sidekiq::ServerMiddleware.
|
||||||
|
|
||||||
|
Currently the middleware API looks like this:
|
||||||
|
|
||||||
|
## Existing Client API
|
||||||
|
|
||||||
|
Client middleware is run when pushing a job to Redis.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class Client
|
||||||
|
def initialize(optional_args)
|
||||||
|
@args = optional_args
|
||||||
|
end
|
||||||
|
def call(worker, job, queue, redis_pool)
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Sidekiq.configure_client do |config|
|
||||||
|
config.client_middleware do |chain|
|
||||||
|
chain.add Client, optional_args
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## Server
|
||||||
|
|
||||||
|
Server middleware is run around job execution.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class Server
|
||||||
|
def initialize(optional_args)
|
||||||
|
@args = optional_args
|
||||||
|
end
|
||||||
|
def call(worker, job, queue)
|
||||||
|
Sidekiq.redis {|c| c.do_something }
|
||||||
|
Sidekiq.logger.info { "Some message" }
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Sidekiq.configure_server do |config|
|
||||||
|
config.server_middleware do |chain|
|
||||||
|
chain.add Server, optional_args
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## Updated API
|
||||||
|
|
||||||
|
The updated middleware API requires the middleware class to include
|
||||||
|
a helper module.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class Client
|
||||||
|
include Sidekiq::ClientMiddleware
|
||||||
|
|
||||||
|
def initialize(optional_args)
|
||||||
|
@args = optional_args
|
||||||
|
end
|
||||||
|
def call(worker, job, queue, redis_pool)
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class Server
|
||||||
|
include Sidekiq::ServerMiddleware
|
||||||
|
|
||||||
|
def initialize(optional_args)
|
||||||
|
@args = optional_args
|
||||||
|
end
|
||||||
|
def call(worker, job, queue)
|
||||||
|
# note we no longer need to use the global Sidekiq module
|
||||||
|
# to access Redis and the logger
|
||||||
|
redis {|c| c.do_something }
|
||||||
|
logger.info { "Some message" }
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
|
@ -199,7 +199,7 @@ module Sidekiq
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.client_middleware
|
def self.client_middleware
|
||||||
@client_chain ||= Middleware::Chain.new
|
@client_chain ||= Middleware::Chain.new(self)
|
||||||
yield @client_chain if block_given?
|
yield @client_chain if block_given?
|
||||||
@client_chain
|
@client_chain
|
||||||
end
|
end
|
||||||
|
@ -211,7 +211,7 @@ module Sidekiq
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.default_server_middleware
|
def self.default_server_middleware
|
||||||
Middleware::Chain.new
|
Middleware::Chain.new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.default_worker_options=(hash) # deprecated
|
def self.default_worker_options=(hash) # deprecated
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "sidekiq/middleware/modules"
|
||||||
|
|
||||||
module Sidekiq
|
module Sidekiq
|
||||||
# Middleware is code configured to run before/after
|
# Middleware is code configured to run before/after
|
||||||
# a message is processed. It is patterned after Rack
|
# a message is processed. It is patterned after Rack
|
||||||
|
@ -44,10 +46,12 @@ module Sidekiq
|
||||||
# This is an example of a minimal server middleware:
|
# This is an example of a minimal server middleware:
|
||||||
#
|
#
|
||||||
# class MyServerHook
|
# class MyServerHook
|
||||||
|
# include Sidekiq::ServerMiddleware
|
||||||
# def call(job_instance, msg, queue)
|
# def call(job_instance, msg, queue)
|
||||||
# puts "Before job"
|
# logger.info "Before job"
|
||||||
|
# redis {|conn| conn.get("foo") } # do something in Redis
|
||||||
# yield
|
# yield
|
||||||
# puts "After job"
|
# logger.info "After job"
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
|
@ -56,10 +60,11 @@ module Sidekiq
|
||||||
# to Redis:
|
# to Redis:
|
||||||
#
|
#
|
||||||
# class MyClientHook
|
# class MyClientHook
|
||||||
|
# include Sidekiq::ClientMiddleware
|
||||||
# def call(job_class, msg, queue, redis_pool)
|
# def call(job_class, msg, queue, redis_pool)
|
||||||
# puts "Before push"
|
# logger.info "Before push"
|
||||||
# result = yield
|
# result = yield
|
||||||
# puts "After push"
|
# logger.info "After push"
|
||||||
# result
|
# result
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
|
@ -76,7 +81,8 @@ module Sidekiq
|
||||||
entries.each(&block)
|
entries.each(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize
|
def initialize(config = nil)
|
||||||
|
@config = config
|
||||||
@entries = nil
|
@entries = nil
|
||||||
yield self if block_given?
|
yield self if block_given?
|
||||||
end
|
end
|
||||||
|
@ -91,24 +97,24 @@ module Sidekiq
|
||||||
|
|
||||||
def add(klass, *args)
|
def add(klass, *args)
|
||||||
remove(klass)
|
remove(klass)
|
||||||
entries << Entry.new(klass, *args)
|
entries << Entry.new(@config, klass, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
def prepend(klass, *args)
|
def prepend(klass, *args)
|
||||||
remove(klass)
|
remove(klass)
|
||||||
entries.insert(0, Entry.new(klass, *args))
|
entries.insert(0, Entry.new(@config, klass, *args))
|
||||||
end
|
end
|
||||||
|
|
||||||
def insert_before(oldklass, newklass, *args)
|
def insert_before(oldklass, newklass, *args)
|
||||||
i = entries.index { |entry| entry.klass == newklass }
|
i = entries.index { |entry| entry.klass == newklass }
|
||||||
new_entry = i.nil? ? Entry.new(newklass, *args) : entries.delete_at(i)
|
new_entry = i.nil? ? Entry.new(@config, newklass, *args) : entries.delete_at(i)
|
||||||
i = entries.index { |entry| entry.klass == oldklass } || 0
|
i = entries.index { |entry| entry.klass == oldklass } || 0
|
||||||
entries.insert(i, new_entry)
|
entries.insert(i, new_entry)
|
||||||
end
|
end
|
||||||
|
|
||||||
def insert_after(oldklass, newklass, *args)
|
def insert_after(oldklass, newklass, *args)
|
||||||
i = entries.index { |entry| entry.klass == newklass }
|
i = entries.index { |entry| entry.klass == newklass }
|
||||||
new_entry = i.nil? ? Entry.new(newklass, *args) : entries.delete_at(i)
|
new_entry = i.nil? ? Entry.new(@config, newklass, *args) : entries.delete_at(i)
|
||||||
i = entries.index { |entry| entry.klass == oldklass } || entries.count - 1
|
i = entries.index { |entry| entry.klass == oldklass } || entries.count - 1
|
||||||
entries.insert(i + 1, new_entry)
|
entries.insert(i + 1, new_entry)
|
||||||
end
|
end
|
||||||
|
@ -149,13 +155,16 @@ module Sidekiq
|
||||||
class Entry
|
class Entry
|
||||||
attr_reader :klass
|
attr_reader :klass
|
||||||
|
|
||||||
def initialize(klass, *args)
|
def initialize(config, klass, *args)
|
||||||
|
@config = config
|
||||||
@klass = klass
|
@klass = klass
|
||||||
@args = args
|
@args = args
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_new
|
def make_new
|
||||||
@klass.new(*@args)
|
x = @klass.new(*@args)
|
||||||
|
x.config = @config if @config && x.respond_to?(:config=)
|
||||||
|
x
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,8 @@ module Sidekiq
|
||||||
#
|
#
|
||||||
module CurrentAttributes
|
module CurrentAttributes
|
||||||
class Save
|
class Save
|
||||||
|
include Sidekiq::ClientMiddleware
|
||||||
|
|
||||||
def initialize(cattr)
|
def initialize(cattr)
|
||||||
@klass = cattr
|
@klass = cattr
|
||||||
end
|
end
|
||||||
|
@ -31,6 +33,8 @@ module Sidekiq
|
||||||
end
|
end
|
||||||
|
|
||||||
class Load
|
class Load
|
||||||
|
include Sidekiq::ServerMiddleware
|
||||||
|
|
||||||
def initialize(cattr)
|
def initialize(cattr)
|
||||||
@klass = cattr
|
@klass = cattr
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,7 @@ module Sidekiq::Middleware::I18n
|
||||||
# Get the current locale and store it in the message
|
# Get the current locale and store it in the message
|
||||||
# to be sent to Sidekiq.
|
# to be sent to Sidekiq.
|
||||||
class Client
|
class Client
|
||||||
|
include Sidekiq::ClientMiddleware
|
||||||
def call(_jobclass, job, _queue, _redis)
|
def call(_jobclass, job, _queue, _redis)
|
||||||
job["locale"] ||= I18n.locale
|
job["locale"] ||= I18n.locale
|
||||||
yield
|
yield
|
||||||
|
@ -18,6 +19,7 @@ module Sidekiq::Middleware::I18n
|
||||||
|
|
||||||
# Pull the msg locale out and set the current thread to use it.
|
# Pull the msg locale out and set the current thread to use it.
|
||||||
class Server
|
class Server
|
||||||
|
include Sidekiq::ServerMiddleware
|
||||||
def call(_jobclass, job, _queue, &block)
|
def call(_jobclass, job, _queue, &block)
|
||||||
I18n.with_locale(job.fetch("locale", I18n.default_locale), &block)
|
I18n.with_locale(job.fetch("locale", I18n.default_locale), &block)
|
||||||
end
|
end
|
||||||
|
|
19
lib/sidekiq/middleware/modules.rb
Normal file
19
lib/sidekiq/middleware/modules.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
module Sidekiq
|
||||||
|
module ServerMiddleware
|
||||||
|
attr_accessor :config
|
||||||
|
def redis_pool
|
||||||
|
config.redis_pool
|
||||||
|
end
|
||||||
|
|
||||||
|
def logger
|
||||||
|
config.logger
|
||||||
|
end
|
||||||
|
|
||||||
|
def redis(&block)
|
||||||
|
config.redis(&block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# no difference for now
|
||||||
|
ClientMiddleware = ServerMiddleware
|
||||||
|
end
|
|
@ -165,4 +165,28 @@ describe Sidekiq::Middleware do
|
||||||
I18n.available_locales = nil
|
I18n.available_locales = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class FooC
|
||||||
|
include Sidekiq::ClientMiddleware
|
||||||
|
def initialize(*args)
|
||||||
|
@args = args
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(w, j, q, rp)
|
||||||
|
redis { |c| c.incr(self.class.name) }
|
||||||
|
logger.info { |c| [self.class.name, @args].inspect }
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "configuration" do
|
||||||
|
it "gets an object which provides redis and logging" do
|
||||||
|
cfg = Sidekiq
|
||||||
|
chain = Sidekiq::Middleware::Chain.new(cfg)
|
||||||
|
chain.add FooC, foo: "bar"
|
||||||
|
final_action = nil
|
||||||
|
chain.invoke(nil, nil, nil, nil) { final_action = true }
|
||||||
|
assert final_action
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue