Class: CC::Service::Invocation

Inherits:
Object
  • Object
show all
Defined in:
lib/cc/service/invocation.rb,
lib/cc/service/invocation/with_metrics.rb,
lib/cc/service/invocation/with_retries.rb,
lib/cc/service/invocation/invocation_chain.rb,
lib/cc/service/invocation/with_return_values.rb,
lib/cc/service/invocation/with_error_handling.rb

Defined Under Namespace

Classes: InvocationChain, WithErrorHandling, WithMetrics, WithRetries, WithReturnValues

Constant Summary collapse

MIDDLEWARE =
{
  retries: WithRetries,
  metrics: WithMetrics,
  error_handling: WithErrorHandling,
  return_values: WithReturnValues,
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(service) {|_self| ... } ⇒ Invocation

Returns a new instance of Invocation.

Yields:

  • (_self)

Yield Parameters:



40
41
42
43
44
45
46
# File 'lib/cc/service/invocation.rb', line 40

def initialize(service)
  @chain = InvocationChain.new { service.receive }

  yield(self) if block_given?

  @result = @chain.call
end

Instance Attribute Details

#resultObject (readonly)

Returns the value of attribute result.



15
16
17
# File 'lib/cc/service/invocation.rb', line 15

def result
  @result
end

Class Method Details

.invoke(service, &block) ⇒ Object

Build a chain of invocation wrappers which eventually calls receive on the given service, then execute that chain.

Order is important. Each call to #with, wraps the last.

Usage:

CC::Service::Invocation.invoke(service) do |i|
  i.with :retries, 3
  i.with :metrics, $statsd
  i.with :error_handling, Rails.logger
end

In the above example, service.receive could happen 4 times (once, then three retries) before an exception is re-raised up to the metrics collector, then up again to the error handling. If the order were reversed, the error handling middleware would prevent the other middleware from seeing any exceptions at all.



35
36
37
38
# File 'lib/cc/service/invocation.rb', line 35

def self.invoke(service, &block)
  instance = new(service, &block)
  instance.result
end

Instance Method Details

#with(middleware, *args) ⇒ Object



48
49
50
51
52
# File 'lib/cc/service/invocation.rb', line 48

def with(middleware, *args)
  if klass = MIDDLEWARE[middleware]
    wrap(klass, *args)
  end
end

#wrap(klass, *args) ⇒ Object



54
55
56
# File 'lib/cc/service/invocation.rb', line 54

def wrap(klass, *args)
  @chain.wrap(klass, *args)
end