diff --git a/lib/von.rb b/lib/von.rb index dc1782e..aca7616 100644 --- a/lib/von.rb +++ b/lib/von.rb @@ -26,12 +26,12 @@ def self.configure yield(config) end - def self.increment(field, value=1) + def self.increment(field, value=1, timestamp=Time.now) parents = field.to_s.sub(PARENT_REGEX, '') - total = increment_counts_for(field, value) + total = increment_counts_for(field, value, timestamp) until parents.empty? do - increment_counts_for(parents, value) + increment_counts_for(parents, value, timestamp) parents.sub!(PARENT_REGEX, '') end @@ -40,23 +40,23 @@ def self.increment(field, value=1) raise e if config.raise_connection_errors end - def self.increment_counts_for(field, value=1) + def self.increment_counts_for(field, value=1, timestamp=Time.now) counter = Counters::Total.new(field) total = counter.increment(value) if config.periods_defined_for_counter?(counter) periods = config.periods[counter.field] - Counters::Period.new(counter.field, periods).increment(value) + Counters::Period.new(counter.field, periods).increment(value, timestamp) end if config.bests_defined_for_counter?(counter) periods = config.bests[counter.field] - Counters::Best.new(counter.field, periods).increment(value) + Counters::Best.new(counter.field, periods).increment(value, timestamp) end if config.currents_defined_for_counter?(counter) periods = config.currents[counter.field] - Counters::Current.new(counter.field, periods).increment(value) + Counters::Current.new(counter.field, periods).increment(value, timestamp) end total diff --git a/lib/von/counters/best.rb b/lib/von/counters/best.rb index 888b18c..756d792 100644 --- a/lib/von/counters/best.rb +++ b/lib/von/counters/best.rb @@ -28,17 +28,17 @@ def current_timestamp(time_unit) hget("#{hash_key}:#{time_unit}:current", 'timestamp') end - def increment(value=1) + def increment(value=1, timestamp=Time.now) return if @periods.empty? @periods.each do |period| _current_timestamp = current_timestamp(period.time_unit) _current_total = current_total(period.time_unit) - if period.timestamp != _current_timestamp + if period.timestamp(timestamp) != _current_timestamp # changing current period hset("#{hash_key}:#{period.time_unit}:current", 'total', value) - hset("#{hash_key}:#{period.time_unit}:current", 'timestamp', period.timestamp) + hset("#{hash_key}:#{period.time_unit}:current", 'timestamp', period.timestamp(timestamp)) if best_total(period) < _current_total hset("#{hash_key}:#{period.time_unit}:best", 'total', _current_total) diff --git a/lib/von/counters/current.rb b/lib/von/counters/current.rb index 1209403..e050774 100644 --- a/lib/von/counters/current.rb +++ b/lib/von/counters/current.rb @@ -20,13 +20,13 @@ def current_timestamp(time_unit) hget("#{hash_key}:#{time_unit}", 'timestamp') end - def increment(value=1) + def increment(value=1, timestamp=Time.now) return if @periods.empty? @periods.each do |period| - if period.timestamp != current_timestamp(period.time_unit) + if period.timestamp(timestamp) != current_timestamp(period.time_unit) hset("#{hash_key}:#{period.time_unit}", 'total', value) - hset("#{hash_key}:#{period.time_unit}", 'timestamp', period.timestamp) + hset("#{hash_key}:#{period.time_unit}", 'timestamp', period.timestamp(timestamp)) else hincrby("#{hash_key}:#{period.time_unit}", 'total', value) end diff --git a/lib/von/counters/period.rb b/lib/von/counters/period.rb index 2d9ef9c..4a4098d 100644 --- a/lib/von/counters/period.rb +++ b/lib/von/counters/period.rb @@ -18,17 +18,17 @@ def list_key(time_unit) "#{Von.config.namespace}:lists:#{@field}:#{time_unit}" end - def increment(value=1) + def increment(value=1, timestamp=Time.now) return if @periods.empty? @periods.each do |period| _hash_key = hash_key(period.time_unit) _list_key = list_key(period.time_unit) - hincrby(_hash_key, period.timestamp, value) + hincrby(_hash_key, period.timestamp(timestamp), value) - unless lrange(_list_key, 0, -1).include?(period.timestamp) - rpush(_list_key, period.timestamp) + unless lrange(_list_key, 0, -1).include?(period.timestamp(timestamp)) + rpush(_list_key, period.timestamp(timestamp)) end if llen(_list_key) > period.length diff --git a/lib/von/counters/total.rb b/lib/von/counters/total.rb index 9e735ac..4117063 100644 --- a/lib/von/counters/total.rb +++ b/lib/von/counters/total.rb @@ -21,7 +21,7 @@ def hash_key # If the key has time periods specified, increment those. # # Returns the Integer total for the key - def increment(value=1) + def increment(value=1, timestamp=nil) hincrby(hash_key, 'total', value).to_i end diff --git a/lib/von/period.rb b/lib/von/period.rb index a6fecbf..c6ae5dc 100644 --- a/lib/von/period.rb +++ b/lib/von/period.rb @@ -61,8 +61,8 @@ def prev(unit = 1) beginning(unit.send(time_unit.to_sym).ago).strftime(@format) end - def timestamp - beginning(Time.now).strftime(format) + def timestamp(time=Time.now) + beginning(time).strftime(format) end def self.unit_to_period(time_unit) diff --git a/test/counters/best_test.rb b/test/counters/best_test.rb index da03e28..0a22406 100644 --- a/test/counters/best_test.rb +++ b/test/counters/best_test.rb @@ -15,10 +15,8 @@ counter.increment - Timecop.freeze(Time.local(2013, 01, 02)) - 4.times { counter.increment(2) } - Timecop.freeze(Time.local(2013, 01, 03)) - 3.times { counter.increment } + 4.times { counter.increment(2, Time.local(2013, 01, 02)) } + 3.times { counter.increment(1, Time.local(2013, 01, 03)) } @redis.hget('von:counters:bests:foo:day:current', 'timestamp').must_equal '2013-01-03' @redis.hget('von:counters:bests:foo:day:current', 'total').must_equal '3' @@ -34,10 +32,8 @@ counter.increment - Timecop.freeze(Time.local(2013, 01, 13, 06, 05)) - 4.times { counter.increment(2) } - Timecop.freeze(Time.local(2013, 01, 20, 06, 10)) - 3.times { counter.increment } + 4.times { counter.increment(2, Time.local(2013, 01, 13, 06, 05)) } + 3.times { counter.increment(1, Time.local(2013, 01, 20, 06, 10)) } @redis.hget('von:counters:bests:foo:minute:current', 'timestamp').must_equal '2013-01-20 06:10' @redis.hget('von:counters:bests:foo:minute:current', 'total').must_equal '3' diff --git a/test/counters/current_test.rb b/test/counters/current_test.rb index b71ba07..28d01b4 100644 --- a/test/counters/current_test.rb +++ b/test/counters/current_test.rb @@ -14,8 +14,7 @@ counter = CurrentCounter.new('foo', [ Von::Period.new(:day) ]) 4.times { counter.increment } - Timecop.freeze(Time.local(2013, 01, 02)) - 3.times { counter.increment(2) } + 3.times { counter.increment(2, Time.local(2013, 01, 02)) } @redis.hget('von:counters:currents:foo:day', 'timestamp').must_equal '2013-01-02' @redis.hget('von:counters:currents:foo:day', 'total').must_equal '6' @@ -28,8 +27,7 @@ ]) 4.times { counter.increment } - Timecop.freeze(Time.local(2013, 01, 20, 06, 10)) - 3.times { counter.increment(2) } + 3.times { counter.increment(2, Time.local(2013, 01, 20, 06, 10)) } @redis.hget('von:counters:currents:foo:minute', 'timestamp').must_equal '2013-01-20 06:10' @redis.hget('von:counters:currents:foo:minute', 'total').must_equal '6' @@ -45,8 +43,7 @@ ]) 4.times { counter.increment } - Timecop.freeze(Time.local(2013, 01, 01, 06, 10)) - 3.times { counter.increment(2) } + 3.times { counter.increment(2, Time.local(2013, 01, 01, 06, 10)) } counter.count(:minute).must_equal 6 counter.count(:day).must_equal 10 diff --git a/test/counters/period_test.rb b/test/counters/period_test.rb index 78fc79c..06bab94 100644 --- a/test/counters/period_test.rb +++ b/test/counters/period_test.rb @@ -42,8 +42,7 @@ ]) counter.increment - Timecop.freeze(Time.local(2013, 02)) - counter.increment(5) + counter.increment(5, Time.local(2013, 02)) @redis.hget('von:counters:foo:month', '2013-02').must_equal '5' @redis.lrange('von:lists:foo:month', 0, -1).size.must_equal 1 @@ -59,11 +58,20 @@ counter.increment counter.increment - Timecop.freeze(Time.local(2013, 02, 01, 7)) - counter.increment(5) - Timecop.freeze(Time.local(2013, 02, 01, 9)) - counter.increment + counter.count(:month).must_equal [{ timestamp: "2013-01", count: 2 }] + counter.count(:hour).must_equal [ + { timestamp: "2012-12-31 20:00", count: 0 }, + { timestamp: "2012-12-31 21:00", count: 0 }, + { timestamp: "2012-12-31 22:00", count: 0 }, + { timestamp: "2012-12-31 23:00", count: 0 }, + { timestamp: "2013-01-01 00:00", count: 0 }, + { timestamp: "2013-01-01 01:00", count: 2 } + ] + counter.increment(5, Time.local(2013, 02, 01, 7)) + counter.increment(1, Time.local(2013, 02, 01, 9)) + + Timecop.freeze(Time.local(2013, 02, 01, 9)) counter.count(:month).must_equal [{ timestamp: "2013-02", count: 6 }] counter.count(:hour).must_equal [ { timestamp: "2013-02-01 04:00", count: 0 },