class Cloudtasker::Middleware::Chain

The class below was originally taken from Sidekiq. See: github.com/mperham/sidekiq/blob/master/lib/sidekiq/middleware/chain.rb

Middleware are callables configured to run before/after a message is processed. Middlewares can be configured to run on the client side (when jobs are pushed to Cloud Tasks) as well as on the server side (when jobs are processed by your application)

To add middleware for the client:

Cloudtasker.configure do |config|

config.client_middleware do |chain|
  chain.add MyClientHook
end

end

To modify middleware for the server, just call with another block:

Cloudtasker.configure do |config|

config.server_middleware do |chain|
  chain.add MyServerHook
  chain.remove ActiveRecord
end

end

To insert immediately preceding another entry:

Cloudtasker.configure do |config|

config.client_middleware do |chain|
  chain.insert_before ActiveRecord, MyClientHook
end

end

To insert immediately after another entry:

Cloudtasker.configure do |config|

config.client_middleware do |chain|
  chain.insert_after ActiveRecord, MyClientHook
end

end

This is an example of a minimal server middleware:

class MyServerHook

def call(worker_instance, msg, queue)
  puts "Before work"
  yield
  puts "After work"
end

end

This is an example of a minimal client middleware, note the method must return the result or the job will not push to Redis:

class MyClientHook

def call(worker_class, msg, queue, redis_pool)
  puts "Before push"
  result = yield
  puts "After push"
  result
end

end

Public Class Methods

new() { |self| ... } click to toggle source

Build a new middleware chain.

# File lib/cloudtasker/middleware/chain.rb, line 76
def initialize
  @entries = nil
  yield self if block_given?
end

Public Instance Methods

add(klass, *args) click to toggle source

Add a middleware at the end of the list.

@param [Class] klass The middleware class to add. @param [Arry<any>] *args The list of arguments to the middleware.

@return [Array<Cloudtasker::Middleware::Chain::Entry>] The updated list of middlewares

# File lib/cloudtasker/middleware/chain.rb, line 116
def add(klass, *args)
  remove(klass) if exists?(klass)
  entries << Entry.new(klass, *args)
end
clear() click to toggle source

Empty the list of middlewares.

@return [Array<Cloudtasker::Middleware::Chain::Entry>] The updated list of middlewares

# File lib/cloudtasker/middleware/chain.rb, line 201
def clear
  entries.clear
end
each(&block) click to toggle source

Iterate over the list middlewares and execute the block on each item.

@param [Proc] &block The block to execute on each item.

# File lib/cloudtasker/middleware/chain.rb, line 86
def each(&block)
  entries.each(&block)
end
empty?() click to toggle source

Checks if the middlware list is empty

@return [Boolean] Return true if the middleware list is empty.

# File lib/cloudtasker/middleware/chain.rb, line 182
def empty?
  @entries.nil? || @entries.empty?
end
entries() click to toggle source

Return the list of middlewares.

@return [Array<Cloudtasker::Middleware::Chain::Entry>] The list of middlewares

# File lib/cloudtasker/middleware/chain.rb, line 95
def entries
  @entries ||= []
end
exists?(klass) click to toggle source

Checks if middleware has been added to the list.

@param [Class] klass The middleware class to check.

@return [Boolean] Return true if the middleware is in the list.

# File lib/cloudtasker/middleware/chain.rb, line 173
def exists?(klass)
  any? { |entry| entry.klass == klass }
end
insert_after(oldklass, newklass, *args) click to toggle source

Add a middleware after another middleware.

@param [Class] oldklass The middleware class after which the new middleware should be inserted. @param [Class] newklass The middleware class to insert. @param [Arry<any>] *args The list of arguments for the inserted middleware.

@return [Array<Cloudtasker::Middleware::Chain::Entry>] The updated list of middlewares

# File lib/cloudtasker/middleware/chain.rb, line 159
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)
  i = entries.index { |entry| entry.klass == oldklass } || entries.count - 1
  entries.insert(i + 1, new_entry)
end
insert_before(oldklass, newklass, *args) click to toggle source

Add a middleware before another middleware.

@param [Class] oldklass The middleware class before which the new middleware should be inserted. @param [Class] newklass The middleware class to insert. @param [Arry<any>] *args The list of arguments for the inserted middleware.

@return [Array<Cloudtasker::Middleware::Chain::Entry>] The updated list of middlewares

# File lib/cloudtasker/middleware/chain.rb, line 143
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)
  i = entries.index { |entry| entry.klass == oldklass } || 0
  entries.insert(i, new_entry)
end
invoke(*args) { || ... } click to toggle source

Invoke the chain of middlewares.

@param [Array<any>] *args The args to pass to each middleware.

# File lib/cloudtasker/middleware/chain.rb, line 210
def invoke(*args)
  return yield if empty?

  chain = retrieve.dup
  traverse_chain = lambda do
    if chain.empty?
      yield
    else
      chain.shift.call(*args, &traverse_chain)
    end
  end
  traverse_chain.call
end
prepend(klass, *args) click to toggle source

Add a middleware at the beginning of the list.

@param [Class] klass The middleware class to add. @param [Arry<any>] *args The list of arguments to the middleware.

@return [Array<Cloudtasker::Middleware::Chain::Entry>] The updated list of middlewares

# File lib/cloudtasker/middleware/chain.rb, line 129
def prepend(klass, *args)
  remove(klass) if exists?(klass)
  entries.insert(0, Entry.new(klass, *args))
end
remove(klass) click to toggle source

Remove a middleware from the list.

@param [Class] klass The middleware class to remove.

# File lib/cloudtasker/middleware/chain.rb, line 104
def remove(klass)
  entries.delete_if { |entry| entry.klass == klass }
end
retrieve() click to toggle source

Return a list of instantiated middlewares. Each middleware gets initialize with the args originally passed to `add`, `insert_before` etc.

@return [Array<any>] The list of instantiated middlewares.

# File lib/cloudtasker/middleware/chain.rb, line 192
def retrieve
  map(&:make_new)
end