lib/coach/request_benchmark.rb
# frozen_string_literal: true
module Coach
# This class is built to aggregate data during the course of the request. It relies on
# 'start_middleware.coach' and 'finish_middleware.coach' events to register the
# start/end of each middleware element, and thereby calculate running times for each.
#
# Coach::Notifications makes use of this class to produce benchmark data for
# requests.
class RequestBenchmark
def initialize(endpoint_name)
@endpoint_name = endpoint_name
@events = []
end
def notify(name, start, finish)
event = { name: name, start: start, finish: finish }
duration_of_children = child_events_for(event).
inject(0) { |total, e| total + e[:duration] }
event[:duration] = (finish - start) - duration_of_children
@events.push(event)
end
def complete(start, finish)
@start = start
@duration = finish - start
end
# Serialize the results of the benchmarking
def stats
{
endpoint_name: @endpoint_name,
started_at: @start,
duration: format_ms(@duration),
duration_seconds: @duration,
chain: sorted_chain.map do |event|
{
name: event[:name],
duration: format_ms(event[:duration]),
duration_seconds: event[:duration],
}
end,
}
end
private
def previous_event
@events.last
end
def child_events_for(parent)
@events.select do |child|
parent[:start] < child[:start] && child[:finish] < parent[:finish]
end
end
def sorted_chain
@events.sort_by { |event| event[:start] }
end
def format_ms(duration)
(1000 * duration).round
end
end
end