1
0
Fork 0
mirror of https://github.com/mperham/sidekiq.git synced 2022-11-09 13:52:34 -05:00
mperham--sidekiq/lib/sidekiq/middleware/chain.rb

145 lines
3.5 KiB
Ruby
Raw Normal View History

2012-02-08 20:04:19 -05:00
module Sidekiq
# Middleware is code configured to run before/after
# a message is processed. It is patterned after Rack
# middleware. Middleware exists for the client side
# (pushing jobs onto the queue) as well as the server
# side (when jobs are actually processed).
2012-02-08 20:04:19 -05:00
#
# To add middleware for the client:
2012-02-08 20:04:19 -05:00
#
2012-07-17 14:06:10 -04:00
# Sidekiq.configure_client do |config|
# config.client_middleware do |chain|
# chain.add MyClientHook
# end
2012-02-08 20:04:19 -05:00
# end
#
# To modify middleware for the server, just call
# with another block:
2012-02-08 20:04:19 -05:00
#
2012-07-17 14:06:10 -04:00
# Sidekiq.configure_server do |config|
# config.server_middleware do |chain|
# chain.add MyServerHook
# chain.remove ActiveRecord
# end
2012-02-08 20:04:19 -05:00
# end
#
# To insert immediately preceding another entry:
#
# Sidekiq.configure_client do |config|
# config.client_middleware do |chain|
# chain.insert_before ActiveRecord, MyClientHook
# end
# end
#
# To insert immediately after another entry:
#
# Sidekiq.configure_client do |config|
# config.client_middleware do |chain|
# chain.insert_after ActiveRecord, MyClientHook
# end
# end
#
2012-02-18 16:08:53 -05:00
# This is an example of a minimal server middleware:
2012-02-08 20:04:19 -05:00
#
# class MyServerHook
2012-07-17 14:06:10 -04:00
# def call(worker_instance, msg, queue)
2012-02-08 20:04:19 -05:00
# puts "Before work"
# yield
# puts "After work"
# end
# end
#
2013-11-14 23:30:11 -05:00
# This is an example of a minimal client middleware, note
# the method must return the result or the job will not push
# to Redis:
2012-02-18 16:08:53 -05:00
#
# class MyClientHook
# def call(worker_class, msg, queue, redis_pool)
2012-02-18 16:08:53 -05:00
# puts "Before push"
2013-11-14 23:30:11 -05:00
# result = yield
2012-02-18 16:08:53 -05:00
# puts "After push"
2013-11-14 23:30:11 -05:00
# result
2012-02-18 16:08:53 -05:00
# end
# end
#
2012-02-08 20:04:19 -05:00
module Middleware
class Chain
2013-07-27 19:14:07 -04:00
include Enumerable
2012-02-08 20:04:19 -05:00
attr_reader :entries
2013-10-26 00:07:54 -04:00
def initialize_copy(copy)
copy.instance_variable_set(:@entries, entries.dup)
end
2013-07-27 19:14:07 -04:00
def each(&block)
entries.each(&block)
end
2012-02-08 20:04:19 -05:00
def initialize
@entries = []
yield self if block_given?
2012-02-08 20:04:19 -05:00
end
def remove(klass)
2012-02-08 20:04:19 -05:00
entries.delete_if { |entry| entry.klass == klass }
end
def add(klass, *args)
remove(klass) if exists?(klass)
entries << Entry.new(klass, *args)
end
def insert_before(oldklass, newklass, *args)
i = entries.index { |entry| entry.klass == newklass }
new_entry = i.nil? ? Entry.new(newklass, *args) : entries.delete_at(i)
2013-09-12 17:14:17 -04:00
i = entries.index { |entry| entry.klass == oldklass } || 0
entries.insert(i, new_entry)
end
def insert_after(oldklass, newklass, *args)
i = entries.index { |entry| entry.klass == newklass }
new_entry = i.nil? ? Entry.new(newklass, *args) : entries.delete_at(i)
2013-09-12 17:14:17 -04:00
i = entries.index { |entry| entry.klass == oldklass } || entries.count - 1
entries.insert(i+1, new_entry)
end
def exists?(klass)
2013-09-12 17:14:17 -04:00
any? { |entry| entry.klass == klass }
2012-02-08 20:04:19 -05:00
end
def retrieve
2013-09-12 17:14:17 -04:00
map(&:make_new)
2012-02-08 20:04:19 -05:00
end
2012-03-17 20:59:18 -04:00
def clear
entries.clear
end
2012-02-08 20:04:19 -05:00
def invoke(*args, &final_action)
chain = retrieve.dup
traverse_chain = lambda do
if chain.empty?
final_action.call
else
chain.shift.call(*args, &traverse_chain)
end
end
traverse_chain.call
end
end
class Entry
attr_reader :klass
2012-02-08 20:04:19 -05:00
def initialize(klass, *args)
@klass = klass
@args = args
end
def make_new
@klass.new(*@args)
end
end
end
end