lib/drone/metrics/meter.rb in drone-0.0.3 vs lib/drone/metrics/meter.rb in drone-1.0.1

- old
+ new

@@ -1,48 +1,68 @@ require 'eventmachine' +require File.expand_path('../metric', __FILE__) require File.expand_path('../../core', __FILE__) require File.expand_path('../../utils/ewma', __FILE__) module Drone module Metrics - # A meter metric which measures mean throughput and one-, five-, and + ## + # A meter measures mean throughput and one-, five-, and # fifteen-minute exponentially-weighted moving average throughputs. - class Meter + # + class Meter < Metric INTERVAL = 5 - attr_reader :count, :name - def initialize(name) - @name = name - @start_time = Time.now - @count = 0 + super(name) + @start_time = Drone::request_number("#{name}:start_time", Time.now) + @next_tick = Drone::request_number("#{name}:next_tick_lock", 1) + + @count = Drone::request_number("#{name}:count", 0) @rates = { - 1 => EWMA.one_minute_ewma, - 5 => EWMA.five_minutes_ewma, - 15 => EWMA.fifteen_minutes_ewma + 1 => EWMA.one_minute_ewma("#{name}:rate1"), + 5 => EWMA.five_minutes_ewma("#{name}:rate5"), + 15 => EWMA.fifteen_minutes_ewma("#{name}:rate15") } - Drone::schedule_periodic(INTERVAL){ tick() } + Drone::schedule_periodic(INTERVAL) do + Fiber.new{ tick() }.resume + end end def tick - @rates.values.each(&:tick) + # init if required + @local_next_tick ||= @next_tick.get + + # ensure only one process will trigger the tick + if @next_tick.compare_and_set(@local_next_tick, @local_next_tick + 1) + @rates.values.each(&:tick) + @local_next_tick += 1 + else + # reset the tick counter to give a chance to this + # process to trigger the next tick + @local_next_tick = @next_tick.get() + end end def mark(events = 1) - @count += events + @count.inc(events) @rates.each do |_, r| r.update(events) end end + + def count + @count.get + end def mean_rate - if @count == 0 + count = @count.get + if count == 0 0.0 else - elapsed = Time.now.to_f - @start_time.to_f - @count / elapsed + count / (Time.now.to_f - @start_time.get.to_f) end end def one_minute_rate @rates[1].rate()