Class: Hitimes::TimedValueMetric

Inherits:
Metric
  • Object
show all
Defined in:
lib/hitimes/timed_value_metric.rb

Overview

A TimedValueMetric holds the metrics on how long it takes to do a batch of something. something. For measuring how long a method takes to operate on N items.

tm = TimedValueMetric.new( 'my-batch-method' )

42.times do
  tm.start
  number_of_items_processed = do_something
  tm.stop( number_of_items_processed )
end

puts "#{ tm.name } operated at a rate of #{ tm.rate } calls per second"

TimedValueMetric combines the usefulness of a ValueMetric and a TimedMetric. The stats are available for both the time it took to do the operation and the sizes of the batches that were run.

A TimedValueMetric keeps track of both the time it took to do an operation and the size of the batch that was operated on. These metrics are kept separately as timed_stats and value_stats accessors.

Instance Attribute Summary collapse

Attributes inherited from Metric

#additional_data, #name, #sampling_delta

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Metric

#sampling_start_time, #sampling_stop_time, #utc_microseconds

Constructor Details

#initialize(name, additional_data = {}) ⇒ TimedValueMetric

:call-seq:

TimedValueMetric.new( 'name') -> TimedValueMetric
TimedValueMetric.new( 'name', 'other' => 'data') -> TimedValueMetric

Create a new TimedValueMetric giving it a name and additional data. additional_data may be anything that follows the to_hash protocol



60
61
62
63
64
65
# File 'lib/hitimes/timed_value_metric.rb', line 60

def initialize(name, additional_data = {})
  super(name, additional_data)
  @timed_stats      = Stats.new
  @value_stats      = Stats.new
  @current_interval = Interval.new
end

Instance Attribute Details

#timed_statsObject (readonly)

holds all the Timed statistics



33
34
35
# File 'lib/hitimes/timed_value_metric.rb', line 33

def timed_stats
  @timed_stats
end

#value_statsObject (readonly)

holds all the Value statistics



36
37
38
# File 'lib/hitimes/timed_value_metric.rb', line 36

def value_stats
  @value_stats
end

Class Method Details

.now(name, additional_data = {}) ⇒ Object

:call-seq:

TimedValueMetric.now( 'name' ) -> TimedValueMetric

Return a TimedValueMetric that has been started



45
46
47
48
49
# File 'lib/hitimes/timed_value_metric.rb', line 45

def now(name, additional_data = {})
  tvm = TimedValueMetric.new(name, additional_data)
  tvm.start
  tvm
end

Instance Method Details

#durationObject

:call-seq:

timed_value_metric.duration -> Float

The duration of measured time from the metric.



174
175
176
# File 'lib/hitimes/timed_value_metric.rb', line 174

def duration
  @timed_stats.sum
end

#measure(value) ⇒ Object

:call-seq:

timed_value_metric.measure( value ) {  ... } -> Object

Measure the execution of a block and add those stats to the running stats. The return value is the return value of the block. A value must be passed into measure to update the value_stats portion of the TimedValueMetric.



131
132
133
134
135
136
137
138
139
140
# File 'lib/hitimes/timed_value_metric.rb', line 131

def measure(value)
  return_value = nil
  begin
    start
    return_value = yield
  ensure
    stop(value)
  end
  return_value
end

#rateObject

:call-seq:

timed_value_metric.rate -> Float

Rate in the context of the TimedValueMetric is different than the TimedMetric. In the TimedValueMetric, each measurement of time is associated with a quantity of things done during that unit of time. So the rate for a TimedValueMetric is the (sum of all quantities sampled) / ( sum of all durations measured )

For example, say you were measuring, using a TimedValueMetric batch jobs that had individual units of work.

tvm = TimedValueMetric.new( 'some-batch' )
tvm.start
# process a batch of 12 units
duration1 = tvm.stop( 12 )

tvm.start
# process a larger batch of 42 units
duration2 = tvm.stop( 42 )

At this point the rate of units per second is calculated as ( 12 + 42 ) / ( duration1 + duration2 )

some_batch_rate = tvm.rate # returns ( 34 / ( duration1+duration2 ) )


214
215
216
# File 'lib/hitimes/timed_value_metric.rb', line 214

def rate
  @value_stats.sum / @timed_stats.sum
end

#running?Boolean

:call-seq:

timed_value_metric.running? -> true or false

return whether or not the metric is currently timing something.

Returns:

  • (Boolean)


73
74
75
# File 'lib/hitimes/timed_value_metric.rb', line 73

def running?
  @current_interval.running?
end

#split(value) ⇒ Object

:call-seq:

timed_value_metric.split( value ) -> Float

Split the current metric. Essentially, mark a split time. This means stop the current interval, with the givein value and create a new interval, but make sure that the new interval lines up exactly, timewise, behind the previous interval.

If the metric is running, then split returns the duration of the previous interval, i.e. the split-time. If the metric is not running, nothing happens, no stats are updated, and false is returned.



156
157
158
159
160
161
162
163
164
165
166
# File 'lib/hitimes/timed_value_metric.rb', line 156

def split(value)
  if @current_interval.running?
    next_interval = @current_interval.split
    duration = @current_interval.duration
    @timed_stats.update(duration)
    @value_stats.update(value)
    @current_interval = next_interval
    return duration
  end
  false
end

#startObject

:call-seq:

timed_value_metric.start -> nil

Start the current timer, if the current timer is already started, then this is a noop.



84
85
86
87
88
89
90
91
# File 'lib/hitimes/timed_value_metric.rb', line 84

def start
  unless @current_interval.running?
    @current_interval.start
    @sampling_start_time ||= utc_microseconds
    @sampling_start_interval ||= Interval.now
  end
  nil
end

#stop(value) ⇒ Object

:call-seq:

timed_value_metric.stop( count ) -> Float or nil

Stop the current metric. The count parameter must be a value to update to the value portion of the TimedValueMetric. Generally this is probably the number of things that were operated upon since start was invoked.

This updates both the value_stats and timed_stats stats and removes the current interval. If the metric is stopped then the duration of the last Interval is returned. If the metric was already stopped before this call, then false is returned and no stats are updated.



108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/hitimes/timed_value_metric.rb', line 108

def stop(value)
  if @current_interval.running?
    duration = @current_interval.stop
    @timed_stats.update(duration)
    @current_interval = Interval.new
    @value_stats.update(value)

    # update the lenght of time we have been sampling
    @sampling_delta = @sampling_start_interval.duration_so_far

    return duration
  end
  false
end

#to_hashObject

:call-seq:

metric.to_hash -> Hash

Convert the metric to a hash



224
225
226
227
228
229
230
231
# File 'lib/hitimes/timed_value_metric.rb', line 224

def to_hash
  result = super
  result["timed_stats"] = @timed_stats.to_hash
  result["value_stats"] = @value_stats.to_hash(Stats::STATS - %w[rate])
  result["rate"] = rate
  result["unit_count"] = unit_count
  result
end

#unit_countObject

:call-seq:

timed_value_metric.unit_count -> Float

The sum of all values passed to stop or skip or measure



184
185
186
# File 'lib/hitimes/timed_value_metric.rb', line 184

def unit_count
  @value_stats.sum
end