Class: Wurk::Middleware::Chain
- Inherits:
-
Object
- Object
- Wurk::Middleware::Chain
- Includes:
- Enumerable
- Defined in:
- lib/wurk/middleware/chain.rb
Overview
Ordered list of middleware bound to a config/capsule. Sidekiq contract: ‘add` appends (removing any existing entry for the same klass), `prepend` pushes to index 0, `insert_before`/`insert_after` anchor relative to an existing entry, `invoke` walks the chain handing the inner block to each.
‘retrieve` instantiates a fresh instance per entry on every job — entries store klass + ctor args, not the live object. This keeps middleware thread-safe by construction and matches Sidekiq’s lifecycle.
Spec: docs/target/sidekiq-free.md §10.1.
Defined Under Namespace
Classes: Entry
Instance Attribute Summary collapse
-
#config ⇒ Object
Returns the value of attribute config.
-
#entries ⇒ Object
readonly
Returns the value of attribute entries.
Instance Method Summary collapse
- #add(klass) ⇒ Object
- #clear ⇒ Object
-
#copy_for(capsule) ⇒ Object
Bind a duplicate of this chain to ‘capsule`.
- #each ⇒ Object
- #empty? ⇒ Boolean
- #exists?(klass) ⇒ Boolean (also: #include?)
-
#initialize(config = nil) {|_self| ... } ⇒ Chain
constructor
A new instance of Chain.
- #insert_after(oldklass, newklass) ⇒ Object
- #insert_before(oldklass, newklass) ⇒ Object
-
#invoke(*args, &block) ⇒ Object
Walks the chain inside-out.
- #prepend(klass) ⇒ Object
- #remove(klass) ⇒ Object
- #retrieve ⇒ Object
Constructor Details
#initialize(config = nil) {|_self| ... } ⇒ Chain
Returns a new instance of Chain.
21 22 23 24 25 |
# File 'lib/wurk/middleware/chain.rb', line 21 def initialize(config = nil) @config = config @entries = [] yield self if block_given? end |
Instance Attribute Details
#config ⇒ Object
Returns the value of attribute config.
19 20 21 |
# File 'lib/wurk/middleware/chain.rb', line 19 def config @config end |
#entries ⇒ Object (readonly)
Returns the value of attribute entries.
18 19 20 |
# File 'lib/wurk/middleware/chain.rb', line 18 def entries @entries end |
Instance Method Details
#add(klass) ⇒ Object
42 43 44 45 |
# File 'lib/wurk/middleware/chain.rb', line 42 def add(klass, *) remove(klass) @entries << Entry.new(klass, *) end |
#clear ⇒ Object
79 80 81 |
# File 'lib/wurk/middleware/chain.rb', line 79 def clear @entries.clear end |
#copy_for(capsule) ⇒ Object
Bind a duplicate of this chain to ‘capsule`. Capsules share the parent config’s entries by reference initially but mutate independently after the first ‘add`/`remove`/etc. (Array#dup on `@entries`).
32 33 34 35 36 |
# File 'lib/wurk/middleware/chain.rb', line 32 def copy_for(capsule) copy = dup copy.instance_variable_set(:@config, capsule) copy end |
#each ⇒ Object
27 |
# File 'lib/wurk/middleware/chain.rb', line 27 def each(&) = @entries.each(&) |
#empty? ⇒ Boolean
71 72 73 |
# File 'lib/wurk/middleware/chain.rb', line 71 def empty? @entries.empty? end |
#exists?(klass) ⇒ Boolean Also known as: include?
66 67 68 |
# File 'lib/wurk/middleware/chain.rb', line 66 def exists?(klass) any? { |entry| entry.klass == klass } end |
#insert_after(oldklass, newklass) ⇒ Object
59 60 61 62 63 64 |
# File 'lib/wurk/middleware/chain.rb', line 59 def insert_after(oldklass, newklass, *) i = @entries.index { |entry| entry.klass == newklass } new_entry = i.nil? ? Entry.new(newklass, *) : @entries.delete_at(i) i = @entries.index { |entry| entry.klass == oldklass } || (@entries.size - 1) @entries.insert(i + 1, new_entry) end |
#insert_before(oldklass, newklass) ⇒ Object
52 53 54 55 56 57 |
# File 'lib/wurk/middleware/chain.rb', line 52 def insert_before(oldklass, newklass, *) i = @entries.index { |entry| entry.klass == newklass } new_entry = i.nil? ? Entry.new(newklass, *) : @entries.delete_at(i) i = @entries.index { |entry| entry.klass == oldklass } || 0 @entries.insert(i, new_entry) end |
#invoke(*args, &block) ⇒ Object
Walks the chain inside-out. Each middleware receives a block that advances to the next; the innermost block is the caller’s ‘&block`, whose return value is propagated back out. Empty chain: `yield`.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/wurk/middleware/chain.rb', line 86 def invoke(*args, &block) raise ArgumentError, 'middleware chain requires a block' unless block return yield if @entries.empty? chain = retrieve traverse = lambda do if chain.empty? block.call else chain.shift.call(*args, &traverse) end end traverse.call end |
#prepend(klass) ⇒ Object
47 48 49 50 |
# File 'lib/wurk/middleware/chain.rb', line 47 def prepend(klass, *) remove(klass) @entries.unshift(Entry.new(klass, *)) end |
#remove(klass) ⇒ Object
38 39 40 |
# File 'lib/wurk/middleware/chain.rb', line 38 def remove(klass) @entries.delete_if { |entry| entry.klass == klass } end |
#retrieve ⇒ Object
75 76 77 |
# File 'lib/wurk/middleware/chain.rb', line 75 def retrieve map { |entry| entry.make_new(@config) } end |