Class: Pancake::Middleware::StackMiddleware

Inherits:
Object
  • Object
show all
Defined in:
lib/pancake/middleware.rb

Overview

StackMiddleware manages the definition of the middleware stack for a given class. It’s instances are responsible for the definition of a single piece of middleware, and the class is responsible for specifying the full stack for a given class.

When Pancake::Middleware extends a class, an inner class is created in that class called StackMiddleware. That StackMiddleware class inherits from Pancake::Middleware::StackMiddleware.

This is then set is an inheritable inner class on the extended class, such that when it is inherited, the StackMiddleware class is inherited to an inner class of the same name on the child.

Examples:

The setup when Pancake::Middleware is extended

MyClass.extend Pancake::Middleware
# sets up

class MyClass
  class StackMiddleware < Pancake::Middleware::StackMiddleware; end
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, stack, options = {}) ⇒ StackMiddleware

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of StackMiddleware.

Parameters:

  • name (Object)

    a name for this middleware definition. Usually a symbol, but could be the class.

  • stack (Object)

    the stack owner of this middleware.

  • options (Hash) (defaults to: {})

    an options hash. Provide labels for this middleware.

Options Hash (options):

  • :labels (Array) — default: [:any]

    The labels that are associated with this middleware

  • :before (Object)

    A middleware name to add this middleware before

  • :after (Object)

    A middleware name to add this middleware after

See Also:

  • Pancake::Middleware.stack_labels


279
280
281
282
# File 'lib/pancake/middleware.rb', line 279

def initialize(name, stack, options = {})
  @name, @stack, @options = name, stack, options
  @options[:labels] ||= [:any]
end

Instance Attribute Details

#argsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



174
175
176
# File 'lib/pancake/middleware.rb', line 174

def args
  @args
end

#blockObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



174
175
176
# File 'lib/pancake/middleware.rb', line 174

def block
  @block
end

#middlewareObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



172
173
174
# File 'lib/pancake/middleware.rb', line 172

def middleware
  @middleware
end

#nameObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



172
173
174
# File 'lib/pancake/middleware.rb', line 172

def name
  @name
end

#optionsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



174
175
176
# File 'lib/pancake/middleware.rb', line 174

def options
  @options
end

#stackObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



174
175
176
# File 'lib/pancake/middleware.rb', line 174

def stack
  @stack
end

Class Method Details

.[](name) ⇒ StackMiddleware

Provides access to a named middleware

Parameters:

  • name (Object)

    The name of the defined middleware

Returns:

Since:

  • 0.1.0



254
255
256
# File 'lib/pancake/middleware.rb', line 254

def [](name)
  _mwares[name]
end

.map_middleware(name, *labels) ⇒ Array<StackMiddleware>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Map the middleware for a given <name>ed middleware. Applies the before and after groups of middlewares

Constructs the middleware list based on the middleware named :foo, including all :before, and :after groups

Examples:

MyClass::StackMiddleware.map_middleware(:foo, :production, :demo)

Parameters:

  • name (Object)

    The name of the middleware to map the before and after groups to

  • labels (Symbol)

    A label or list of labels to use to construct the middleware stack

Returns:

  • (Array<StackMiddleware>)

    Provides an array of StackMiddleware instances in the array [<before :foo>, <:foo>, <after :foo>]

Since:

  • 0.1.0



232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/pancake/middleware.rb', line 232

def map_middleware(name, *labels)
  result = []
  _before[name] ||= []
  _after[name]  ||= []
  if _mwares[name] && _mwares[name].use_for_labels?(*labels)
    result << _before[name].map{|n| map_middleware(n)}
    result << _mwares[name]
    result << _after[name].map{|n| map_middleware(n)}
    result.flatten
  end
  result
end

.middlewares(*labels) ⇒ Array<StackMiddleware>

Get the middleware list for this StackMiddleware for the given labels

This will include all defined middlewares in the given stack

Examples:

Specified labels

MyClass::StackMiddleware.middlewares(:production, :demo)

No Labels Specified

MyClass::StackMiddleware.middlewares

Parameters:

  • labels (Symbol)

    The label or list of labels to construct a stack from.

Returns:

  • (Array<StackMiddleware>)

    An array of the middleware definitions to use in the order that they should be applied Takes into account all :before, :after settings and only constructs the stack where the labels are applied

See Also:

Since:

  • 0.1.0



210
211
212
213
214
# File 'lib/pancake/middleware.rb', line 210

def middlewares(*labels)
  _central_mwares.map do |name|
    map_middleware(name, *labels)
  end.flatten
end

.reset!Object

Resets this stack middlware. Useful for specs



182
183
184
185
186
187
# File 'lib/pancake/middleware.rb', line 182

def reset!
  _central_mwares.clear
  _mwares.clear
  _before.clear
  _after.clear
end

.use(mware, *_args, &block) ⇒ Object



177
178
179
# File 'lib/pancake/middleware.rb', line 177

def use(mware, *_args, &block)
  new(mware).use(mware, *_args, &block)
end

Instance Method Details

#[](name) ⇒ Object

Provides access to a named middleware

See Also:

Since:

  • 0.1.0



264
265
266
# File 'lib/pancake/middleware.rb', line 264

def [](name)
  self.class._mwares[name]
end

#delete!Object

Delete this middleware from the current stack

Since:

  • 0.1.0



289
290
291
292
293
294
295
# File 'lib/pancake/middleware.rb', line 289

def delete!
  self.class._mwares.delete(name)
  self.class._before.delete(name)
  self.class._after.delete(name)
  self.class._central_mwares.delete(name)
  self
end

#dupObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



339
340
341
342
343
344
# File 'lib/pancake/middleware.rb', line 339

def dup
  result = super
  result.args = result.args.map{|element| element.dup}
  result.options = result.options.dup
  result
end

#use(mware, *_args) { ... } ⇒ Object

Specify the actual middleware definition to use

Parameters:

  • mware (Class)

    A Middleware class to use. This should be a class of Middleware which conforms to the Rack spec

  • config (Hash)

    A configuration hash to give to the middleware class on initialization

Yields:

  • The block is passed to the middleware on initialization

See Also:

  • Pancake::Middleware.use

Since:

  • 0.1.0



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/pancake/middleware.rb', line 307

def use(mware, *_args, &block)
  @middleware, @args, @block = mware, _args, block
  @name = @middleware if name.nil?
  if options[:before]
    raise "#{options[:before].inspect} middleware is not defined for this stack" unless self.class._mwares.keys.include?(options[:before])
    self.class._before[options[:before]] ||= []
    self.class._before[options[:before]] << name
  elsif options[:after]
    raise "#{options[:after].inspect} middleware is not defined for this stack" unless self.class._mwares.keys.include?(options[:after])
    self.class._after[options[:after]] ||= []
    self.class._after[options[:after]] << name
  else
    self.class._central_mwares << name unless self.class._central_mwares.include?(name)
  end
  self.class._mwares[name] = self
  self
end

#use_for_labels?(*labels) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks if this middleware definition should be included from the labels given

Parameters:

  • labels (Symbol)

    The label or list of labels to check if this middleware should be included

Returns:

  • (Boolean)

    true if this middlware should be included

Since:

  • 0.1.0



333
334
335
336
# File 'lib/pancake/middleware.rb', line 333

def use_for_labels?(*labels)
  return true if labels.empty? || options[:labels].nil? || options[:labels].include?(:any)
  !(options[:labels] & labels).empty?
end