Class: Toaster::TimeStamp

Inherits:
Object
  • Object
show all
Defined in:
lib/toaster/util/timestamp.rb

Overview

Class that keeps track of timestamps, computes durations, etc. The implementation is not thread-safe.

Constant Summary collapse

@@timestamps =
{}
@@output =
true
@@listeners =
[]
@@mutex =
Mutex.new

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.TIME_SERVICE_URLObject

Returns the value of attribute TIME_SERVICE_URL.



25
26
27
# File 'lib/toaster/util/timestamp.rb', line 25

def TIME_SERVICE_URL
  @TIME_SERVICE_URL
end

Class Method Details

.add(time = nil, key = "__default__") ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/toaster/util/timestamp.rb', line 29

def self.add(time=nil, key="__default__")
  previous = nil
  @@mutex.synchronize do
    time = TimeStamp.now() if !time
    time = time.to_f
    @@timestamps[key] = [] if !@@timestamps[key]
    previous = @@timestamps[key].empty? ? nil : @@timestamps[key][-1]
    @@timestamps[key] << time
    #puts "INFO: Adding timestamp #{time} for key '#{key}'"
  end
  notify(key, time, previous)
end

.add_and_print(action = "n/a", format = nil, key = "__default__", &block) ⇒ Object



93
94
95
96
# File 'lib/toaster/util/timestamp.rb', line 93

def self.add_and_print(action="n/a", format=nil, key="__default__", &block)
  add(nil, key)
  print(action, format, key, &block)
end

.add_listener(l) ⇒ Object



98
99
100
101
102
# File 'lib/toaster/util/timestamp.rb', line 98

def self.add_listener(l)
  @@mutex.synchronize do
    @@listeners << l
  end
end

.clear_listenersObject



104
105
106
107
108
# File 'lib/toaster/util/timestamp.rb', line 104

def self.clear_listeners()
  @@mutex.synchronize do
    @@listeners.clear()
  end
end

.do_output(output) ⇒ Object



68
69
70
# File 'lib/toaster/util/timestamp.rb', line 68

def self.do_output(output)
  @@output = output
end

.notify(key, stamp, previous_stamp) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/toaster/util/timestamp.rb', line 110

def self.notify(key, stamp, previous_stamp)
  keys_to_remove = Set.new
  l_copy = []
  @@mutex.synchronize do
    l_copy = @@listeners.dup
  end
  l_copy.each do |l|
    removes = l.notify(key, stamp, previous_stamp)
    removes = Set.new if !removes || !removes.respond_to?("each")
    removes.each do |r|
      keys_to_remove << r
    end
  end
  @@mutex.synchronize do
    keys_to_remove.each do |k|
      @@timestamps.delete(k)
    end
  end
end

.now(retries = 2) ⇒ Object

Returns the current time in seconds since the Epoch, with float precision.

This method accesses a small “time service” on another host. The reason why we need this is that we have experienced some of the LXC containers (which get spawned on the testing host) actually change the host’s system time..(!) So, if we are simply measuring the local system time on the test host, our time measurements result in bogus data.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/toaster/util/timestamp.rb', line 52

def self.now(retries = 2)
  (0..retries).each do |i|
    out = `curl -s "#{TimeStamp.TIME_SERVICE_URL}" 2> /dev/null`
    out = out.strip
    if out.match(/^[0-9\.]+$/)
      return out.to_i
    else
      sleep 0.5
      # run next attempt in next iteration
    end
  end
  # fallback, if the time service is unavailable...
  puts "WARN: Time service not available (#{retries + 1} attempts), URL: '#{TimeStamp.TIME_SERVICE_URL}'"
  return Time.new.to_f
end


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/toaster/util/timestamp.rb', line 72

def self.print(action="n/a", format=nil, key="__default__", &block)
  format = "Duration for '%s': %d seconds (%.3f ms)\n" if !format
  diff = 0
  t1 = 0
  t2 = 0
  @@mutex.synchronize do
    t1 = @@timestamps[key][-2]
    t2 = @@timestamps[key][-1]
    diff = t2 - t1
  end
  if @@output
    do_print = true
    if block
      do_print = block.call(diff, t1, t2)
    end
    if do_print
      printf(format, action, diff.to_f.round, diff) 
    end
  end
end