class Webmachine::Trace::TraceResource

Implements the user-interface of the visual debugger. This includes serving the static files (the PNG flow diagram, CSS and JS for the UI) and the HTML for the individual traces.

Constants

MAP_EXTERNAL
MAP_FILE
SCRIPT_EXTERNAL
SCRIPT_FILE
STYLE_EXTERNAL
STYLE_FILE
TRACELIST_ERB
TRACE_ERB

Public Class Methods

trace() click to toggle source

The ERB template for a single trace

# File lib/webmachine/trace/trace_resource.rb, line 25
def self.trace
  @@trace ||= ERB.new(File.read(TRACE_ERB))
end
tracelist() click to toggle source

The ERB template for the trace list

# File lib/webmachine/trace/trace_resource.rb, line 20
def self.tracelist
  @@tracelist ||= ERB.new(File.read(TRACELIST_ERB))
end

Public Instance Methods

content_types_provided() click to toggle source
# File lib/webmachine/trace/trace_resource.rb, line 29
def content_types_provided
  case request.path_tokens
  when []
    [['text/html', :produce_list]]
  when MAP_EXTERNAL
    [['image/png', :produce_file]]
  when SCRIPT_EXTERNAL
    [['text/javascript', :produce_file]]
  when STYLE_EXTERNAL
    [['text/css', :produce_file]]
  else
    [['text/html', :produce_trace]]
  end
end
encode_decisions(decisions) click to toggle source
# File lib/webmachine/trace/trace_resource.rb, line 101
def encode_decisions(decisions)
  decisions.each_with_object([]) do |event, list|
    case event[:type]
    when :decision
      # Don't produce new decisions for sub-steps in the graph
      unless /[a-z]$/.match?(event[:decision].to_s)
        list << {'d' => event[:decision], 'calls' => []}
      end
    when :attempt
      list.last['calls'] << {
        'call' => event[:name],
        'source' => event[:source],
        'input' => event[:args] && event[:args].inspect
      }
    when :result
      list.last['calls'].last['output'] = event[:value].inspect
    when :exception
      list.last['calls'].last['exception'] = {
        'class' => event[:class],
        'backtrace' => event[:backtrace].join("\n"),
        'message' => event[:message]
      }
    end
  end
end
encode_trace(data) click to toggle source
# File lib/webmachine/trace/trace_resource.rb, line 91
def encode_trace(data)
  data = data.dup
  # Request is first, response is last
  treq = data.shift.dup
  tres = data.pop.dup
  treq.delete :type
  tres.delete :type
  [MultiJson.dump(treq), MultiJson.dump(tres), MultiJson.dump(encode_decisions(data))]
end
expires() click to toggle source
# File lib/webmachine/trace/trace_resource.rb, line 67
def expires
  (Time.now + 30 * 86400).utc if @file
end
last_modified() click to toggle source
# File lib/webmachine/trace/trace_resource.rb, line 63
def last_modified
  File.mtime(@file) if @file
end
produce_file() click to toggle source
# File lib/webmachine/trace/trace_resource.rb, line 71
def produce_file
  # TODO: Add support for IO objects as response bodies,
  # allowing server optimizations like sendfile or chunked
  # downloads
  File.binread(@file)
end
produce_list() click to toggle source
# File lib/webmachine/trace/trace_resource.rb, line 78
def produce_list
  base = request.uri.path.chomp('/')
  traces = Trace.traces.map { |t| [t, "#{base}/#{t}"] }
  self.class.tracelist.result(binding)
end
produce_trace() click to toggle source
# File lib/webmachine/trace/trace_resource.rb, line 84
def produce_trace
  data = Trace.fetch(@trace)
  treq, tres, trace = encode_trace(data)
  name = @trace
  self.class.trace.result(binding)
end
resource_exists?() click to toggle source
# File lib/webmachine/trace/trace_resource.rb, line 44
def resource_exists?
  case request.path_tokens
  when []
    true
  when MAP_EXTERNAL
    @file = MAP_FILE
    File.exist?(MAP_FILE)
  when SCRIPT_EXTERNAL
    @file = SCRIPT_FILE
    File.exist?(SCRIPT_FILE)
  when STYLE_EXTERNAL
    @file = STYLE_FILE
    File.exist?(STYLE_FILE)
  else
    @trace = request.path_tokens.first
    Trace.traces.include? @trace
  end
end