Class: CMDx::Middlewares
- Inherits:
-
Object
- Object
- CMDx::Middlewares
- Defined in:
- lib/cmdx/middlewares.rb
Overview
Ordered list of middlewares wrapping a task’s lifecycle. Each middleware is a callable with the signature ‘call(task) { next_link.call }`; Runtime builds a nested chain and requires each middleware to yield to the next.
Instance Attribute Summary collapse
-
#registry ⇒ Object
readonly
Returns the value of attribute registry.
Instance Method Summary collapse
-
#deregister(middleware = nil, at: nil) ⇒ Middlewares
Removes a middleware by reference or by index.
- #empty? ⇒ Boolean
-
#initialize ⇒ Middlewares
constructor
A new instance of Middlewares.
- #initialize_copy(source) ⇒ void
-
#process(task) { ... } ⇒ void
Walks the middleware chain around ‘task`’s lifecycle.
-
#register(callable = nil, **options, &block) { ... } ⇒ Middlewares
Inserts a middleware.
- #size ⇒ Integer
Constructor Details
#initialize ⇒ Middlewares
Returns a new instance of Middlewares.
11 12 13 |
# File 'lib/cmdx/middlewares.rb', line 11 def initialize @registry = [] end |
Instance Attribute Details
#registry ⇒ Object (readonly)
Returns the value of attribute registry.
9 10 11 |
# File 'lib/cmdx/middlewares.rb', line 9 def registry @registry end |
Instance Method Details
#deregister(middleware = nil, at: nil) ⇒ Middlewares
Removes a middleware by reference or by index.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/cmdx/middlewares.rb', line 66 def deregister(middleware = nil, at: nil) if at.nil? && middleware.nil? raise ArgumentError, "provide either a middleware or an at: index" elsif !at.nil? && !middleware.nil? raise ArgumentError, "provide either a middleware or an at: index, not both" elsif !at.nil? && !at.is_a?(Integer) raise ArgumentError, "at must be an Integer" end if at.nil? registry.reject! { |mw, _opts| mw == middleware } else registry.delete_at(at) end self end |
#empty? ⇒ Boolean
85 86 87 |
# File 'lib/cmdx/middlewares.rb', line 85 def empty? registry.empty? end |
#initialize_copy(source) ⇒ void
This method returns an undefined value.
17 18 19 |
# File 'lib/cmdx/middlewares.rb', line 17 def initialize_copy(source) @registry = source.registry.dup end |
#process(task) { ... } ⇒ void
This method returns an undefined value.
Walks the middleware chain around ‘task`’s lifecycle. The final link yields to ‘block`, which is expected to run the actual lifecycle.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/cmdx/middlewares.rb', line 102 def process(task) processed = false count = registry.size chain = lambda do |i| if i == count processed = true yield else mw, opts = registry[i] if Util.satisfied?(opts[:if], opts[:unless], task) mw.call(task) { chain.call(i + 1) } else chain.call(i + 1) end end end chain.call(0) processed || begin raise MiddlewareError, "middleware did not yield the next_link" end end |
#register(callable = nil, **options, &block) { ... } ⇒ Middlewares
Inserts a middleware. With no ‘:at`, appends. With `:at`, inserts at the given (clamped) index — supports negative indexing. `:if`/`:unless` gates evaluated against the task at process time.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/cmdx/middlewares.rb', line 35 def register(callable = nil, **, &block) middleware = callable || block at = .delete(:at) if callable && block raise ArgumentError, "provide either a callable or a block, not both" elsif !middleware.respond_to?(:call) raise ArgumentError, "middleware must respond to #call" elsif !at.nil? && !at.is_a?(Integer) raise ArgumentError, "at must be an Integer" end entry = [middleware, .freeze] if at.nil? registry << entry else at = [at.clamp(-registry.size - 1, registry.size), registry.size].min registry.insert(at, entry) end self end |
#size ⇒ Integer
90 91 92 |
# File 'lib/cmdx/middlewares.rb', line 90 def size registry.size end |