class BBLib::TaskTimer

Simple timer that can track tasks based on time. Also provides aggregated metrics

and history for each task run. Generally useful for benchmarking or logging.

@author Brandon Black @attr [Hash] tasks The information on all running tasks and history of all tasks up to the retention. @attr [Integer] retention The number of runs to collect per task before truncation.

Constants

STATS_IGNORE
TIMER_TYPES

Public Instance Methods

active?(task = :default) click to toggle source
# File lib/bblib/core/classes/task_timer.rb, line 79
def active?(task = :default)
  return false unless tasks.keys.include?(task)
  !tasks[task][:current].nil?
end
clear(task = :default) click to toggle source

Removes all history for a given task

@param [Symbol] task The name of the task to clear history from. @return [NilClass] Returns nil

# File lib/bblib/core/classes/task_timer.rb, line 45
def clear(task = :default)
  return nil unless tasks.keys.include?(task)
  stop task
  tasks[task][:history].clear
end
method_missing(*args, **named) click to toggle source
Calls superclass method
# File lib/bblib/core/classes/task_timer.rb, line 92
def method_missing(*args, **named)
  temp   = args.first.to_sym
  type   = TIMER_TYPES.keys.find { |k| k == temp || TIMER_TYPES[k].include?(temp) }
  return super unless type
  t = time(args[1] || :default, type)
  return t if type == :count || !named[:pretty]
  t.is_a?(Array) ? t.map(&:to_duration) : t.to_duration
end
respond_to_missing?(method, include_private = false) click to toggle source
Calls superclass method
# File lib/bblib/core/classes/task_timer.rb, line 101
def respond_to_missing?(method, include_private = false)
  TIMER_TYPES.keys.find { |k| k == method || TIMER_TYPES[k].include?(method) } || super
end
restart(task = :default) click to toggle source
# File lib/bblib/core/classes/task_timer.rb, line 75
def restart(task = :default)
  start(task) unless stop(task).nil?
end
start(task = :default) click to toggle source

Start a new timer for the referenced task. If a timer is already running for that task it will be stopped first.

@param [Symbol] task The name of the task to start. @return [Integer] Returns 0

# File lib/bblib/core/classes/task_timer.rb, line 55
def start(task = :default)
  tasks[task] = { history: [], current: nil } unless tasks.keys.include?(task)
  stop task if tasks[task][:current]
  tasks[task][:current] = Time.now.to_f
  0
end
stats(task = :default, pretty: false) click to toggle source
# File lib/bblib/core/classes/task_timer.rb, line 84
def stats(task = :default, pretty: false)
  return nil unless tasks.include?(task)
  TIMER_TYPES.map do |k, _v|
    next if STATS_IGNORE.include?(k)
    [k, send(k, task, pretty: pretty)]
  end.compact.to_h
end
stop(task = :default) click to toggle source

Stop the referenced timer.

@param [Symbol] task The name of the task to stop. @return [Float, NilClass] The amount of time the task had been running or nil if no matching task was found.

# File lib/bblib/core/classes/task_timer.rb, line 66
def stop(task = :default)
  return nil unless tasks.keys.include?(task) && active?(task)
  time_taken = Time.now.to_f - tasks[task][:current].to_f
  tasks[task][:history] << { start: tasks[task][:current], stop: Time.now.to_f, time: time_taken }
  tasks[task][:current] = nil
  if retention && tasks[task][:history].size > retention then tasks[task][:history].shift end
  time_taken
end
time(task = :default, type = :current) click to toggle source

Returns an aggregated metric for a given type.

@param [Symbol] task The key value of the task to retrieve @param [Symbol] type The metric to return.

Options are :avg, :min, :max, :first, :last, :sum, :all and :count.

@return [Float, Integer, Array] Returns either the aggregation (Numeric) or an Array in the case of :all.

# File lib/bblib/core/classes/task_timer.rb, line 21
def time(task = :default, type = :current)
  return nil unless tasks.keys.include?(task)
  numbers = tasks[task][:history].map { |v| v[:time] }
  case type
  when :current
    return nil unless tasks[task][:current]
    Time.now.to_f - tasks[task][:current]
  when :min, :max, :first, :last
    numbers.send(type)
  when :avg
    numbers.size.zero? ? nil : numbers.inject { |sum, n| sum + n }.to_f / numbers.size
  when :sum
    numbers.inject { |sum, n| sum + n }
  when :all
    numbers
  when :count
    numbers.size
  end
end

Protected Instance Methods

simple_init(*args) click to toggle source
# File lib/bblib/core/classes/task_timer.rb, line 121
def simple_init(*args)
  start(args.first) if args.first.is_a?(Symbol)
end