class Webmachine::Trace::ResourceProxy

This class is injected into the decision FSM as a stand-in for the resource when tracing is enabled. It proxies all callbacks to the resource so that they get logged in the trace.

Constants

CALLBACK_REFERRERS

Callback methods that can return data that refers to user-defined callbacks that are not in the canonical set, including body-producing or accepting methods, encoders and charsetters.

Attributes

resource[R]

@return [Webmachine::Resource] the wrapped resource

Public Class Methods

new(resource) click to toggle source

Creates a {ResourceProxy} that decorates the passed {Webmachine::Resource} such that callbacks invoked by the {Webmachine::Decision::FSM} will be logged in the response’s trace.

# File lib/webmachine/trace/resource_proxy.rb, line 23
def initialize(resource)
  @resource = resource
  @dynamic_callbacks = Module.new
  extend @dynamic_callbacks
end

Public Instance Methods

charset_nop(*args) click to toggle source
# File lib/webmachine/trace/resource_proxy.rb, line 36
def charset_nop(*args)
  proxy_callback :charset_nop, *args
end
finish_request(*args) click to toggle source

Calls the resource’s finish_request method and then sets the trace id header in the response.

# File lib/webmachine/trace/resource_proxy.rb, line 42
def finish_request(*args)
  proxy_callback :finish_request, *args
ensure
  resource.response.headers['X-Webmachine-Trace-Id'] = object_id.to_s
end

Private Instance Methods

add_dynamic_callback_proxies(pairs) click to toggle source

Adds proxy methods for callbacks that are dynamically referred to.

# File lib/webmachine/trace/resource_proxy.rb, line 95
def add_dynamic_callback_proxies(pairs)
  pairs.to_a.each do |(_, m)|
    unless respond_to?(m)
      @dynamic_callbacks.module_eval do
        define_method m do |*args|
          proxy_callback m, *args
        end
      end
    end
  end
end
attempt(callback, args) click to toggle source

Creates a log entry for the entry to a resource callback.

# File lib/webmachine/trace/resource_proxy.rb, line 66
def attempt(callback, args)
  log = {type: :attempt}
  method = resource.method(callback)
  if method.owner == ::Webmachine::Resource::Callbacks
    log[:name] = "(default)##{method.name}"
  else
    log[:name] = "#{method.owner.name}##{method.name}"
    log[:source] = method.source_location.join(':') if method.respond_to?(:source_location)
  end
  unless args.empty?
    log[:args] = args
  end
  log
end
exception(e) click to toggle source

Creates a log entry for an exception that was raised from a callback

# File lib/webmachine/trace/resource_proxy.rb, line 87
def exception(e)
  {type: :exception,
   class: e.class.name,
   backtrace: e.backtrace,
   message: e.message}
end
proxy_callback(callback, *args) click to toggle source

Proxy a given callback to the inner resource, decorating with traces

# File lib/webmachine/trace/resource_proxy.rb, line 51
def proxy_callback(callback, *args)
  # Log inputs and attempt
  resource.response.trace << attempt(callback, args)
  # Do the call
  _result = resource.send(callback, *args)
  add_dynamic_callback_proxies(_result) if CALLBACK_REFERRERS.include?(callback.to_sym)
  resource.response.trace << result(_result)
  _result
rescue => exc
  exc.backtrace.reject! { |s| s.include?(__FILE__) }
  resource.response.trace << exception(exc)
  raise
end
result(result) click to toggle source

Creates a log entry for the result of a resource callback

# File lib/webmachine/trace/resource_proxy.rb, line 82
def result(result)
  {type: :result, value: result}
end