time_window_drop_collector 0.0.11 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/time_window_drop_collector.rb +25 -4
- data/lib/time_window_drop_collector/logger.rb +1 -1
- data/lib/time_window_drop_collector/results.rb +11 -0
- data/lib/time_window_drop_collector/storage.rb +10 -34
- data/lib/time_window_drop_collector/utils.rb +49 -0
- data/lib/time_window_drop_collector/version.rb +1 -1
- data/lib/time_window_drop_collector/wrappers/memcache.rb +8 -4
- data/lib/time_window_drop_collector/wrappers/mock.rb +6 -4
- data/lib/time_window_drop_collector/wrappers/rails_cache.rb +6 -5
- data/lib/time_window_drop_collector/wrappers/redis.rb +15 -5
- data/test/logger_test.rb +9 -0
- data/test/mock_wrapper_test.rb +5 -4
- data/test/rails_cache_wrapper_test.rb +5 -5
- data/test/redis_wrapper_test.rb +8 -5
- data/test/storage_test.rb +85 -56
- data/test/time_window_drop_collector_test.rb +44 -4
- metadata +16 -14
@@ -3,8 +3,10 @@ require "dalli"
|
|
3
3
|
require_relative "time_window_drop_collector/version"
|
4
4
|
require_relative "time_window_drop_collector/config"
|
5
5
|
require_relative "time_window_drop_collector/logger"
|
6
|
+
require_relative "time_window_drop_collector/utils"
|
6
7
|
require_relative "time_window_drop_collector/storage"
|
7
8
|
require_relative "time_window_drop_collector/wrapper"
|
9
|
+
require_relative "time_window_drop_collector/results"
|
8
10
|
require_relative "time_window_drop_collector/wrappers/memcache"
|
9
11
|
require_relative "time_window_drop_collector/wrappers/mock"
|
10
12
|
require_relative "time_window_drop_collector/wrappers/redis"
|
@@ -14,6 +16,8 @@ class TimeWindowDropCollector
|
|
14
16
|
attr_reader :config, :wrapper, :storage
|
15
17
|
|
16
18
|
def initialize( &block )
|
19
|
+
TimeWindowDropCollector::Logger.log "INITIALIZING version: #{TimeWindowDropCollector::VERSION}"
|
20
|
+
|
17
21
|
@config = {
|
18
22
|
:window => 600,
|
19
23
|
:slices => 10,
|
@@ -23,15 +27,32 @@ class TimeWindowDropCollector
|
|
23
27
|
|
24
28
|
@config.merge!( TimeWindowDropCollector::Config.extract( block ) ) if block_given?
|
25
29
|
|
30
|
+
TimeWindowDropCollector::Logger.log "CONFIG: #{config}"
|
31
|
+
|
26
32
|
@wrapper = TimeWindowDropCollector::Wrapper.instance( config[:client], config[:client_opts] )
|
27
33
|
@storage = TimeWindowDropCollector::Storage.new( wrapper, config[:window], config[:slices] )
|
28
34
|
end
|
29
35
|
|
30
|
-
def drop(
|
31
|
-
|
36
|
+
def drop( keys )
|
37
|
+
keys = [keys] unless keys.is_a? Array
|
38
|
+
keys = keys.map(&:to_s)
|
39
|
+
|
40
|
+
TimeWindowDropCollector::Logger.log "DROP keys: #{keys.join(", ")}"
|
41
|
+
storage.incr( keys )
|
32
42
|
end
|
33
43
|
|
34
|
-
def count(
|
35
|
-
|
44
|
+
def count( orig_keys )
|
45
|
+
keys = orig_keys.is_a?(Array) ? orig_keys : [orig_keys]
|
46
|
+
keys = keys.map(&:to_s)
|
47
|
+
|
48
|
+
TimeWindowDropCollector::Logger.log "COUNT keys: #{keys.join(", ")}"
|
49
|
+
|
50
|
+
result = storage.count( keys )
|
51
|
+
result = TimeWindowDropCollector::Results.new( result )
|
52
|
+
result = result[orig_keys.to_s] unless orig_keys.is_a? Array
|
53
|
+
|
54
|
+
TimeWindowDropCollector::Logger.log "COUNT result: #{result}"
|
55
|
+
|
56
|
+
result
|
36
57
|
end
|
37
58
|
end
|
@@ -1,46 +1,22 @@
|
|
1
1
|
class TimeWindowDropCollector::Storage
|
2
|
+
include TimeWindowDropCollector::Utils
|
3
|
+
|
2
4
|
attr_reader :wrapper, :window, :slices
|
3
5
|
|
4
6
|
def initialize( wrapper, window, slices )
|
5
7
|
@wrapper = wrapper
|
6
|
-
@window
|
7
|
-
@slices
|
8
|
-
end
|
9
|
-
|
10
|
-
def incr( key )
|
11
|
-
wrapper.incr( time_key( key ), window )
|
12
|
-
end
|
13
|
-
|
14
|
-
def count( key )
|
15
|
-
time_keys = time_keys( key )
|
16
|
-
values = wrapper.values_for( time_keys )
|
17
|
-
|
18
|
-
values.map( &:to_i ).inject( :+ ).to_i
|
19
|
-
end
|
20
|
-
|
21
|
-
def time_key( key, time = timestamp )
|
22
|
-
"drop_window_#{key}_#{slice_start_timestamp( time )}"
|
23
|
-
end
|
24
|
-
|
25
|
-
def time_keys( key )
|
26
|
-
now = timestamp
|
27
|
-
|
28
|
-
( 0..( slices - 1 ) ).map{ |i|
|
29
|
-
time_key( key, now - ( ( i*slice_milliseconds ) / 1000 ) )
|
30
|
-
}
|
31
|
-
end
|
32
|
-
|
33
|
-
def timestamp
|
34
|
-
Time.now
|
8
|
+
@window = window
|
9
|
+
@slices = slices
|
35
10
|
end
|
36
11
|
|
37
|
-
def
|
38
|
-
(
|
12
|
+
def incr( keys )
|
13
|
+
wrapper.incr( timestamp_key_multi( keys ), window )
|
39
14
|
end
|
40
15
|
|
41
|
-
def
|
42
|
-
|
16
|
+
def count( keys )
|
17
|
+
window_keys = window_keys_multi( keys )
|
18
|
+
keys_values = wrapper.get( window_keys )
|
43
19
|
|
44
|
-
(
|
20
|
+
grouping_count( keys_values )
|
45
21
|
end
|
46
22
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module TimeWindowDropCollector::Utils
|
2
|
+
def grouping_count( key_values )
|
3
|
+
groups = key_values.group_by { |k,v| k.match( /drop_window_(.*)_/ )[1] }
|
4
|
+
|
5
|
+
result = {}
|
6
|
+
|
7
|
+
groups.each do |k,v|
|
8
|
+
result[k] = v.inject(0) { |acc,e| acc += e[1].to_i }
|
9
|
+
end
|
10
|
+
|
11
|
+
result
|
12
|
+
end
|
13
|
+
|
14
|
+
def timestamp_key( key, time = timestamp )
|
15
|
+
"drop_window_#{key}_#{slice_start_timestamp( time )}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def timestamp_key_multi( keys )
|
19
|
+
now = timestamp
|
20
|
+
|
21
|
+
keys.map { |key| timestamp_key( key, now ) }.flatten
|
22
|
+
end
|
23
|
+
|
24
|
+
def window_keys( key, now = timestamp )
|
25
|
+
( 0..( slices - 1 ) ).map{ |i|
|
26
|
+
timestamp_key( key, now - ( ( i*slice_milliseconds ) / 1000 ) )
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def window_keys_multi( keys )
|
31
|
+
now = timestamp
|
32
|
+
|
33
|
+
keys.map { |key| window_keys( key, now ) }.flatten
|
34
|
+
end
|
35
|
+
|
36
|
+
def timestamp
|
37
|
+
Time.now
|
38
|
+
end
|
39
|
+
|
40
|
+
def slice_milliseconds
|
41
|
+
@slice_milliseconds ||= ( window * 1000 ) / slices
|
42
|
+
end
|
43
|
+
|
44
|
+
def slice_start_timestamp( time )
|
45
|
+
time_milliseconds = ( time.to_f * 1000 ).truncate
|
46
|
+
|
47
|
+
( time_milliseconds / slice_milliseconds ) * slice_milliseconds
|
48
|
+
end
|
49
|
+
end
|
@@ -7,12 +7,16 @@ class TimeWindowDropCollector
|
|
7
7
|
@client = Dalli::Client.new( opts )
|
8
8
|
end
|
9
9
|
|
10
|
-
def incr(
|
11
|
-
client.
|
10
|
+
def incr( keys, expire_time )
|
11
|
+
client.multi do
|
12
|
+
keys.each do |key|
|
13
|
+
client.incr( key, 1, expire_time, 1 )
|
14
|
+
end
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
|
-
def
|
15
|
-
client.get_multi( keys )
|
18
|
+
def get( keys )
|
19
|
+
client.get_multi( keys )
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
@@ -7,12 +7,14 @@ class TimeWindowDropCollector
|
|
7
7
|
@client = MemcacheMock.new
|
8
8
|
end
|
9
9
|
|
10
|
-
def incr(
|
11
|
-
|
10
|
+
def incr( keys, expire_time )
|
11
|
+
keys.each do |key|
|
12
|
+
client.incr( key, 1, nil, 1 )
|
13
|
+
end
|
12
14
|
end
|
13
15
|
|
14
|
-
def
|
15
|
-
client.get_multi( keys )
|
16
|
+
def get( keys )
|
17
|
+
client.get_multi( keys )
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
@@ -7,13 +7,14 @@ class TimeWindowDropCollector
|
|
7
7
|
@client = Rails.cache
|
8
8
|
end
|
9
9
|
|
10
|
-
def incr(
|
11
|
-
|
12
|
-
|
10
|
+
def incr( keys, expire_time )
|
11
|
+
keys.each do |key|
|
12
|
+
client.increment( key, 1, :expires_in => expire_time )
|
13
|
+
end
|
13
14
|
end
|
14
15
|
|
15
|
-
def
|
16
|
-
client.read_multi( keys )
|
16
|
+
def get( keys )
|
17
|
+
client.read_multi( keys )
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
@@ -7,15 +7,25 @@ class TimeWindowDropCollector
|
|
7
7
|
@client = ::Redis.new( opts )
|
8
8
|
end
|
9
9
|
|
10
|
-
def incr(
|
10
|
+
def incr( keys, expire_time )
|
11
11
|
client.multi do
|
12
|
-
|
13
|
-
|
12
|
+
keys.each do |key|
|
13
|
+
client.incr( key )
|
14
|
+
client.expire( key, expire_time )
|
15
|
+
end
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
17
|
-
def
|
18
|
-
client.mget( *keys )
|
19
|
+
def get( keys )
|
20
|
+
values = client.mget( *keys )
|
21
|
+
|
22
|
+
result = {}
|
23
|
+
|
24
|
+
keys.each_with_index do |key, i|
|
25
|
+
result[key] = values[i]
|
26
|
+
end
|
27
|
+
|
28
|
+
result
|
19
29
|
end
|
20
30
|
end
|
21
31
|
end
|
data/test/logger_test.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
require_relative "test_helper"
|
2
2
|
|
3
3
|
class LoggerTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@old_env = ENV["TWDC_DEBUG"]
|
6
|
+
ENV["TWDC_DEBUG"] = "on"
|
7
|
+
end
|
8
|
+
|
9
|
+
def teardown
|
10
|
+
ENV["TWDC_DEBUG"] = @old_env
|
11
|
+
end
|
12
|
+
|
4
13
|
def test_log
|
5
14
|
IO.any_instance.expects( :puts ).with( "[TWDC 2001-02-01 04:05:06] hello!" )
|
6
15
|
|
data/test/mock_wrapper_test.rb
CHANGED
@@ -9,13 +9,14 @@ class MockWrapperTest < Test::Unit::TestCase
|
|
9
9
|
|
10
10
|
def test_incr
|
11
11
|
wrapper = TimeWindowDropCollector::Wrappers::Mock.new( ["arg1"] )
|
12
|
-
wrapper.client.expects( :incr ).with( "
|
13
|
-
wrapper.incr( "
|
12
|
+
wrapper.client.expects( :incr ).with( "key1", 1, nil, 1 )
|
13
|
+
wrapper.client.expects( :incr ).with( "key2", 1, nil, 1 )
|
14
|
+
wrapper.incr( ["key1", "key2"], "expire_time" )
|
14
15
|
end
|
15
16
|
|
16
17
|
def test_values_for
|
17
18
|
wrapper = TimeWindowDropCollector::Wrappers::Mock.new( ["arg1"] )
|
18
|
-
wrapper.client.expects( :get_multi ).with( "keys" ).returns(
|
19
|
-
assert_equal(
|
19
|
+
wrapper.client.expects( :get_multi ).with( "keys" ).returns( "keys_values" )
|
20
|
+
assert_equal( "keys_values", wrapper.get( "keys" ))
|
20
21
|
end
|
21
22
|
end
|
@@ -14,15 +14,15 @@ class MemcacheWrapperTest < Test::Unit::TestCase
|
|
14
14
|
|
15
15
|
def test_incr
|
16
16
|
wrapper = TimeWindowDropCollector::Wrappers::RailsCache.new( ["arg1"] )
|
17
|
-
wrapper.client.expects( :
|
18
|
-
wrapper.client.expects( :
|
17
|
+
wrapper.client.expects( :increment ).with( "key1", 1, :expires_in => "expire_time" )
|
18
|
+
wrapper.client.expects( :increment ).with( "key2", 1, :expires_in => "expire_time" )
|
19
19
|
|
20
|
-
wrapper.incr( "
|
20
|
+
wrapper.incr( ["key1", "key2"], "expire_time" )
|
21
21
|
end
|
22
22
|
|
23
23
|
def test_values_for
|
24
24
|
wrapper = TimeWindowDropCollector::Wrappers::RailsCache.new( ["arg1"] )
|
25
|
-
wrapper.client.expects( :read_multi ).with( "keys" ).returns(
|
26
|
-
assert_equal(
|
25
|
+
wrapper.client.expects( :read_multi ).with( "keys" ).returns( "keys_values" )
|
26
|
+
assert_equal( "keys_values", wrapper.get( "keys" ))
|
27
27
|
end
|
28
28
|
end
|
data/test/redis_wrapper_test.rb
CHANGED
@@ -21,10 +21,13 @@ class RedisWrapperTest < Test::Unit::TestCase
|
|
21
21
|
Redis.expects( :new ).returns( RedisMock.new )
|
22
22
|
wrapper = TimeWindowDropCollector::Wrappers::Redis.new( nil )
|
23
23
|
|
24
|
-
wrapper.client.expects( :incr ).with( "
|
25
|
-
wrapper.client.expects( :expire ).with( "
|
24
|
+
wrapper.client.expects( :incr ).with( "key1" )
|
25
|
+
wrapper.client.expects( :expire ).with( "key1", "expire_time" )
|
26
26
|
|
27
|
-
wrapper.incr( "
|
27
|
+
wrapper.client.expects( :incr ).with( "key2" )
|
28
|
+
wrapper.client.expects( :expire ).with( "key2", "expire_time" )
|
29
|
+
|
30
|
+
wrapper.incr( ["key1", "key2"], "expire_time" )
|
28
31
|
end
|
29
32
|
|
30
33
|
def test_incr_agregates_commands_under_multi
|
@@ -36,12 +39,12 @@ class RedisWrapperTest < Test::Unit::TestCase
|
|
36
39
|
wrapper.incr( nil, nil )
|
37
40
|
end
|
38
41
|
|
39
|
-
def
|
42
|
+
def test_get
|
40
43
|
Redis.expects( :new ).returns( RedisMock.new )
|
41
44
|
wrapper = TimeWindowDropCollector::Wrappers::Redis.new( nil )
|
42
45
|
|
43
46
|
wrapper.client.expects( :mget ).with( "key1", "key2" ).returns( [1, 2] )
|
44
47
|
|
45
|
-
assert_equal(
|
48
|
+
assert_equal( { "key1" => 1, "key2" => 2 }, wrapper.get( ["key1", "key2"] ))
|
46
49
|
end
|
47
50
|
end
|
data/test/storage_test.rb
CHANGED
@@ -2,21 +2,21 @@ require_relative "test_helper"
|
|
2
2
|
|
3
3
|
class StorageTest < Test::Unit::TestCase
|
4
4
|
def setup
|
5
|
-
@
|
6
|
-
@storage = TimeWindowDropCollector::Storage.new( @
|
5
|
+
@wrapper = mock()
|
6
|
+
@storage = TimeWindowDropCollector::Storage.new( @wrapper, 600, 10 )
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
9
|
+
def test_timestamp_key_when_time_is_present
|
10
10
|
timestamp = Time.new( 2001, 2, 3, 4, 5 )
|
11
|
-
assert_equal( "drop_window_key_981169500000", @storage.
|
11
|
+
assert_equal( "drop_window_key_981169500000", @storage.timestamp_key( "key", timestamp ) )
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
14
|
+
def test_timestamp_key_when_time_is_not_present
|
15
15
|
@storage.stubs( :timestamp ).returns( Time.new( 2012, 4, 3, 2, 1 ))
|
16
|
-
assert_equal( "drop_window_key_1333411260000", @storage.
|
16
|
+
assert_equal( "drop_window_key_1333411260000", @storage.timestamp_key( "key" ))
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
19
|
+
def test_window_keys_should_return_10_keys_for_the_last_10_minutes
|
20
20
|
keys = [
|
21
21
|
"drop_window_key_1325560800000",
|
22
22
|
"drop_window_key_1325560740000",
|
@@ -31,56 +31,87 @@ class StorageTest < Test::Unit::TestCase
|
|
31
31
|
]
|
32
32
|
|
33
33
|
Delorean.time_travel_to( '2012-01-03 04:20' ) do
|
34
|
-
assert_equal( keys, @storage.
|
34
|
+
assert_equal( keys, @storage.window_keys( "key" ))
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_incr
|
39
|
-
@storage.expects( :
|
40
|
-
@
|
39
|
+
@storage.expects( :timestamp_key_multi ).with( ["keys"] ).returns( "timestamp_keys" )
|
40
|
+
@wrapper.expects( :incr ).with( "timestamp_keys", 600 )
|
41
41
|
|
42
|
-
@storage.incr( "
|
42
|
+
@storage.incr( ["keys"] )
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_count
|
46
|
-
keys
|
47
|
-
|
48
|
-
|
49
|
-
"drop_window_key_201201031414",
|
50
|
-
"drop_window_key_201201031413",
|
51
|
-
"drop_window_key_201201031412"
|
52
|
-
]
|
46
|
+
@storage.expects( :window_keys_multi ).with( "keys" ).returns( "window_keys" )
|
47
|
+
@wrapper.expects( :get ).with( "window_keys" ).returns( "keys_values" )
|
48
|
+
@storage.expects( :grouping_count ).with( "keys_values" ).returns( "grouping_keys_counts" )
|
53
49
|
|
54
|
-
|
50
|
+
assert_equal( "grouping_keys_counts", @storage.count( "keys" ))
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_grouping_count
|
54
|
+
key_values = {
|
55
|
+
"drop_window_key1_201201031416" => 1,
|
56
|
+
"drop_window_key1_201201031415" => 2,
|
57
|
+
"drop_window_key1_201201031414" => 3,
|
58
|
+
"drop_window_key1_201201031413" => 4,
|
59
|
+
"drop_window_key1_201201031412" => 5,
|
60
|
+
"drop_window_key2_201201031413" => 6,
|
61
|
+
"drop_window_key2_201201031412" => 7
|
62
|
+
}
|
63
|
+
|
64
|
+
key_counts = @storage.grouping_count( key_values )
|
65
|
+
|
66
|
+
assert_equal( 15, key_counts["key1"])
|
67
|
+
assert_equal( 13, key_counts["key2"])
|
68
|
+
end
|
55
69
|
|
56
|
-
|
57
|
-
|
70
|
+
def test_grouping_count_with_nil_values
|
71
|
+
key_values = {
|
72
|
+
"drop_window_key1_201201031416" => 1,
|
73
|
+
"drop_window_key1_201201031414" => nil,
|
74
|
+
"drop_window_key2_201201031413" => 6,
|
75
|
+
"drop_window_key2_201201031412" => 7,
|
76
|
+
"drop_window_key3_201201031412" => nil
|
77
|
+
}
|
58
78
|
|
59
|
-
|
79
|
+
key_counts = @storage.grouping_count( key_values )
|
80
|
+
|
81
|
+
assert_equal( 1, key_counts["key1"])
|
82
|
+
assert_equal( 13, key_counts["key2"])
|
83
|
+
assert_equal( 0, key_counts["key3"])
|
60
84
|
end
|
61
85
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
86
|
+
def test_grouping_when_not_key
|
87
|
+
key_values = {
|
88
|
+
"drop_window_key1_201201031416" => 1,
|
89
|
+
"drop_window_key2_201201031412" => 7
|
90
|
+
}
|
91
|
+
|
92
|
+
key_counts = @storage.grouping_count( key_values )
|
93
|
+
|
94
|
+
assert_equal( 1, key_counts["key1"])
|
95
|
+
assert_equal( 7, key_counts["key2"])
|
96
|
+
assert_equal( nil, key_counts["key3"])
|
66
97
|
end
|
67
98
|
|
68
99
|
def test_integration_count
|
69
100
|
client = TimeWindowDropCollector::Wrapper.instance( :mock )
|
70
101
|
storage = TimeWindowDropCollector::Storage.new( client, 600, 10 )
|
71
102
|
|
72
|
-
key_1
|
73
|
-
key_2
|
74
|
-
key_3
|
103
|
+
storage.incr( ["key_1"] )
|
104
|
+
storage.incr( ["key_2"] )
|
105
|
+
storage.incr( ["key_3"] )
|
106
|
+
storage.incr( ["key_2"] )
|
107
|
+
storage.incr( ["key_2", "key_1"] )
|
75
108
|
|
76
|
-
storage.
|
77
|
-
storage.incr( key_2 )
|
78
|
-
storage.incr( key_3 )
|
79
|
-
storage.incr( key_2 )
|
109
|
+
keys_values = storage.count( ["key_1", "key_2", "key_3", "key_4"] )
|
80
110
|
|
81
|
-
assert_equal(
|
82
|
-
assert_equal(
|
83
|
-
assert_equal( 1,
|
111
|
+
assert_equal( 2, keys_values["key_1"])
|
112
|
+
assert_equal( 3, keys_values["key_2"])
|
113
|
+
assert_equal( 1, keys_values["key_3"])
|
114
|
+
assert_equal( nil, keys_values["key_4"])
|
84
115
|
end
|
85
116
|
|
86
117
|
def test_slice_start_timestamp
|
@@ -156,79 +187,77 @@ class StorageTest < Test::Unit::TestCase
|
|
156
187
|
client = TimeWindowDropCollector::Wrapper.instance( :mock )
|
157
188
|
storage = TimeWindowDropCollector::Storage.new( client, 600, 10 )
|
158
189
|
|
159
|
-
key_1 = 1
|
160
|
-
|
161
190
|
Delorean.time_travel_to( '2012-01-03 11:00' ) do
|
162
|
-
storage.incr( key_1 )
|
191
|
+
storage.incr( ["key_1"] )
|
163
192
|
end
|
164
193
|
|
165
194
|
Delorean.time_travel_to( '2012-01-03 11:01' ) do
|
166
|
-
storage.incr( key_1 )
|
195
|
+
storage.incr( ["key_1"] )
|
167
196
|
end
|
168
197
|
|
169
198
|
Delorean.time_travel_to( '2012-01-03 11:02' ) do
|
170
|
-
storage.incr( key_1 )
|
199
|
+
storage.incr( ["key_1"] )
|
171
200
|
end
|
172
201
|
|
173
202
|
Delorean.time_travel_to( '2012-01-03 11:03' ) do
|
174
|
-
storage.incr( key_1 )
|
203
|
+
storage.incr( ["key_1"] )
|
175
204
|
end
|
176
205
|
|
177
206
|
Delorean.time_travel_to( '2012-01-03 11:04' ) do
|
178
|
-
storage.incr( key_1 )
|
207
|
+
storage.incr( ["key_1"] )
|
179
208
|
end
|
180
209
|
|
181
210
|
Delorean.time_travel_to( '2012-01-03 11:05' ) do
|
182
|
-
storage.incr( key_1 )
|
211
|
+
storage.incr( ["key_1"] )
|
183
212
|
end
|
184
213
|
|
185
214
|
Delorean.time_travel_to( '2012-01-03 11:06' ) do
|
186
|
-
storage.incr( key_1 )
|
215
|
+
storage.incr( ["key_1"] )
|
187
216
|
end
|
188
217
|
|
189
218
|
Delorean.time_travel_to( '2012-01-03 11:07' ) do
|
190
|
-
storage.incr( key_1 )
|
219
|
+
storage.incr( ["key_1"] )
|
191
220
|
end
|
192
221
|
|
193
222
|
Delorean.time_travel_to( '2012-01-03 11:08' ) do
|
194
|
-
storage.incr( key_1 )
|
223
|
+
storage.incr( ["key_1"] )
|
195
224
|
end
|
196
225
|
|
197
226
|
Delorean.time_travel_to( '2012-01-03 11:09' ) do
|
198
|
-
storage.incr( key_1 )
|
227
|
+
storage.incr( ["key_1"] )
|
199
228
|
end
|
200
229
|
|
201
230
|
Delorean.time_travel_to( '2012-01-03 11:10' ) do
|
202
|
-
storage.incr( key_1 )
|
231
|
+
storage.incr( ["key_1"] )
|
203
232
|
end
|
204
233
|
|
205
234
|
# counters
|
206
235
|
Delorean.time_travel_to( '2012-01-03 10:59' ) do
|
207
|
-
assert_equal(
|
236
|
+
assert_equal( nil, storage.count( ["key_1"] )["key_1"] )
|
208
237
|
end
|
209
238
|
|
210
239
|
Delorean.time_travel_to( '2012-01-03 11:00' ) do
|
211
|
-
assert_equal( 1, storage.count( key_1 ))
|
240
|
+
assert_equal( 1, storage.count( ["key_1"] )["key_1"] )
|
212
241
|
end
|
213
242
|
|
214
243
|
Delorean.time_travel_to( '2012-01-03 11:05' ) do
|
215
|
-
assert_equal( 6, storage.count( key_1 ))
|
244
|
+
assert_equal( 6, storage.count( ["key_1"] )["key_1"] )
|
216
245
|
end
|
217
246
|
|
218
247
|
Delorean.time_travel_to( '2012-01-03 11:10' ) do
|
219
|
-
assert_equal( 10,
|
248
|
+
assert_equal( 10, storage.count( ["key_1"] )["key_1"])
|
220
249
|
end
|
221
250
|
|
222
251
|
Delorean.time_travel_to( '2012-01-03 11:15' ) do
|
223
|
-
assert_equal( 5, storage.count( key_1 ))
|
252
|
+
assert_equal( 5, storage.count( ["key_1"] )["key_1"] )
|
224
253
|
end
|
225
254
|
|
226
255
|
Delorean.time_travel_to( '2012-01-03 11:19' ) do
|
227
|
-
assert_equal( 1,
|
256
|
+
assert_equal( 1, storage.count( ["key_1"] )["key_1"] )
|
228
257
|
end
|
229
258
|
|
230
259
|
Delorean.time_travel_to( '2012-01-03 11:20' ) do
|
231
|
-
assert_equal(
|
260
|
+
assert_equal( nil, storage.count( ["key_1"] )["key_1"] )
|
232
261
|
end
|
233
262
|
end
|
234
263
|
end
|
@@ -2,7 +2,6 @@ require_relative "test_helper"
|
|
2
2
|
|
3
3
|
class TimeWindowDropCollectorTest < Test::Unit::TestCase
|
4
4
|
def setup
|
5
|
-
@twdc = TimeWindowDropCollector::Logger.stubs( :log )
|
6
5
|
end
|
7
6
|
|
8
7
|
def test_initialize_with_empty_config
|
@@ -34,7 +33,7 @@ class TimeWindowDropCollectorTest < Test::Unit::TestCase
|
|
34
33
|
|
35
34
|
def test_drop
|
36
35
|
storage = mock()
|
37
|
-
storage.expects( :incr ).with( "key" )
|
36
|
+
storage.expects( :incr ).with( ["key"] )
|
38
37
|
|
39
38
|
twdc = TimeWindowDropCollector.new
|
40
39
|
twdc.stubs( :storage ).returns( storage )
|
@@ -44,12 +43,12 @@ class TimeWindowDropCollectorTest < Test::Unit::TestCase
|
|
44
43
|
|
45
44
|
def test_count
|
46
45
|
storage = mock()
|
47
|
-
storage.expects( :count ).with( "key" )
|
46
|
+
storage.expects( :count ).with( ["key"] ).returns( { "key" => 10 } )
|
48
47
|
|
49
48
|
twdc = TimeWindowDropCollector.new
|
50
49
|
twdc.stubs( :storage ).returns( storage )
|
51
50
|
|
52
|
-
twdc.count( "key" )
|
51
|
+
assert_equal( 10, twdc.count( "key" ) )
|
53
52
|
end
|
54
53
|
|
55
54
|
def test_integration_new
|
@@ -67,4 +66,45 @@ class TimeWindowDropCollectorTest < Test::Unit::TestCase
|
|
67
66
|
assert_equal( 100, twdc.storage.window )
|
68
67
|
assert_equal( 20, twdc.storage.slices )
|
69
68
|
end
|
69
|
+
|
70
|
+
def test_integration_drop_and_count
|
71
|
+
twdc = TimeWindowDropCollector.new { client :mock }
|
72
|
+
|
73
|
+
twdc.drop( "key_1" )
|
74
|
+
twdc.drop( "key_1" )
|
75
|
+
twdc.drop( "key_2" )
|
76
|
+
twdc.drop( "key_2" )
|
77
|
+
twdc.drop( ["key_2"] )
|
78
|
+
twdc.drop( ["key_3", "key_4", "key_5"] )
|
79
|
+
|
80
|
+
assert_equal( 2, twdc.count( "key_1" ) )
|
81
|
+
assert_equal( 3, twdc.count( "key_2" ) )
|
82
|
+
assert_equal( 1, twdc.count( "key_3" ) )
|
83
|
+
assert_equal( 1, twdc.count( "key_4" ) )
|
84
|
+
assert_equal( 1, twdc.count( "key_5" ) )
|
85
|
+
assert_equal( 0, twdc.count( "key_6" ) )
|
86
|
+
|
87
|
+
assert_equal( 2, twdc.count( ["key_1", "key_2"] )["key_1"] )
|
88
|
+
assert_equal( 3, twdc.count( ["key_1", "key_2"] )["key_2"] )
|
89
|
+
assert_equal( 0, twdc.count( ["key_6"] )["key_6"] )
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_integration_drop_array_keys
|
93
|
+
twdc = TimeWindowDropCollector.new { client :mock }
|
94
|
+
|
95
|
+
twdc.drop( ["key_1", "key_2"] )
|
96
|
+
|
97
|
+
assert_equal( 1, twdc.count( "key_1" ) )
|
98
|
+
assert_equal( 1, twdc.count( "key_2" ) )
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_integration_drop_and_count_with_numerical_keys
|
102
|
+
twdc = TimeWindowDropCollector.new { client :mock }
|
103
|
+
|
104
|
+
twdc.drop( 1000 )
|
105
|
+
twdc.drop( [1001])
|
106
|
+
|
107
|
+
assert_equal( 1, twdc.count( 1000 ) )
|
108
|
+
assert_equal( 1, twdc.count( 1001 ) )
|
109
|
+
end
|
70
110
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: time_window_drop_collector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-01-
|
13
|
+
date: 2012-01-26 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
17
|
-
requirement: &
|
17
|
+
requirement: &70135818124120 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - =
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: 1.0.21
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *70135818124120
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: rake
|
28
|
-
requirement: &
|
28
|
+
requirement: &70135818123620 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - =
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: 0.9.2.2
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *70135818123620
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: mocha
|
39
|
-
requirement: &
|
39
|
+
requirement: &70135818123160 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - =
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: 0.10.0
|
45
45
|
type: :development
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *70135818123160
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: delorean
|
50
|
-
requirement: &
|
50
|
+
requirement: &70135818122700 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - =
|
@@ -55,10 +55,10 @@ dependencies:
|
|
55
55
|
version: 1.2.0
|
56
56
|
type: :development
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *70135818122700
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: memcache_mock
|
61
|
-
requirement: &
|
61
|
+
requirement: &70135818122240 !ruby/object:Gem::Requirement
|
62
62
|
none: false
|
63
63
|
requirements:
|
64
64
|
- - =
|
@@ -66,10 +66,10 @@ dependencies:
|
|
66
66
|
version: 0.0.1
|
67
67
|
type: :development
|
68
68
|
prerelease: false
|
69
|
-
version_requirements: *
|
69
|
+
version_requirements: *70135818122240
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: dalli
|
72
|
-
requirement: &
|
72
|
+
requirement: &70135818121860 !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
75
|
- - ! '>='
|
@@ -77,7 +77,7 @@ dependencies:
|
|
77
77
|
version: '0'
|
78
78
|
type: :runtime
|
79
79
|
prerelease: false
|
80
|
-
version_requirements: *
|
80
|
+
version_requirements: *70135818121860
|
81
81
|
description: Counter storage system for a concrete time window
|
82
82
|
email:
|
83
83
|
- fguillen.mail@gmail.com
|
@@ -95,7 +95,9 @@ files:
|
|
95
95
|
- lib/time_window_drop_collector.rb
|
96
96
|
- lib/time_window_drop_collector/config.rb
|
97
97
|
- lib/time_window_drop_collector/logger.rb
|
98
|
+
- lib/time_window_drop_collector/results.rb
|
98
99
|
- lib/time_window_drop_collector/storage.rb
|
100
|
+
- lib/time_window_drop_collector/utils.rb
|
99
101
|
- lib/time_window_drop_collector/version.rb
|
100
102
|
- lib/time_window_drop_collector/wrapper.rb
|
101
103
|
- lib/time_window_drop_collector/wrappers/memcache.rb
|