event-counter 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -2
- data/CHANGELOG.md +5 -1
- data/README.md +11 -8
- data/lib/event_counter.rb +9 -4
- data/lib/event_counter/version.rb +1 -1
- data/spec/lib/event_counter_spec.rb +20 -21
- data/spec/lib/performance_spec.rb +3 -3
- data/spec/support/matchers.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0bd855f0622ba4699ac98ae5f11d635fff270bbc
|
4
|
+
data.tar.gz: 996454629b26cf7eb0ce21338f5a5c443fd79713
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16a2277eeb66b50ca1110700ab4fc40497714b5fd928599e4310da1055ff62e38b44a4db6cd004f447bea28169219bb628f1a32c43265bd8e74f404a20a423f3
|
7
|
+
data.tar.gz: c67d8bcab89dcf2bdfd2f99b466e439269af57e13647c7fd13f93594efe4a19e1d49d4845e0d591080b5c31e0b4230e5c1f3e4ae0bdd6d8f20af31df2a5bb882
|
data/.travis.yml
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 1.9.3
|
4
3
|
- 2.0.0
|
5
4
|
- 2.1.0
|
6
5
|
|
@@ -10,7 +9,7 @@ gemfile:
|
|
10
9
|
- gemfiles/pg_ar_32.gemfile
|
11
10
|
- gemfiles/pg_ar_40.gemfile
|
12
11
|
|
13
|
-
script: RUN_ALL=true rspec spec
|
12
|
+
script: RUN_ALL=true bundle exec rspec spec
|
14
13
|
|
15
14
|
services:
|
16
15
|
- postgresql
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[](https://travis-ci.org/skyeagle/event-counter)
|
2
|
+
|
1
3
|
# EventCounter
|
2
4
|
|
3
5
|
EventCounter is a database based event counter with throttling per time intervals.
|
@@ -69,8 +71,8 @@ article.data_for(:views, interval: 10.minutes)
|
|
69
71
|
# ]
|
70
72
|
|
71
73
|
# with range
|
72
|
-
range_start = Time.
|
73
|
-
range_end = Time.
|
74
|
+
range_start = Time.zone.local(2014, 10, 16, 23, 0)
|
75
|
+
range_end = Time.zone.local(2014, 10, 16, 23, 10)
|
74
76
|
range = range_start..range_end
|
75
77
|
article.data_for(:views, interval: 10.minutes, range: range)
|
76
78
|
#=> [
|
@@ -79,8 +81,8 @@ article.data_for(:views, interval: 10.minutes, range: range)
|
|
79
81
|
# ]
|
80
82
|
|
81
83
|
# for different time zone (although we have no data for that time)
|
82
|
-
range_start = Time.
|
83
|
-
range_end = Time.
|
84
|
+
range_start = Time.zone.local(2014, 10, 16, 23, 0).in_time_zone('UTC')
|
85
|
+
range_end = Time.zone.local(2014, 10, 16, 23, 10).in_time_zone('UTC')
|
84
86
|
range = range_start..range_end
|
85
87
|
article.data_for(:views, interval: 10.minutes, range: range, tz: 'UTC')
|
86
88
|
#=> [
|
@@ -98,8 +100,8 @@ article.data_for(:views, interval: :day, raw: true)
|
|
98
100
|
# looks as `Time.zone.parse(i['created_at']), i['value'].to_i ]`
|
99
101
|
|
100
102
|
# class wide
|
101
|
-
range_start = Time.
|
102
|
-
range_end = Time.
|
103
|
+
range_start = Time.zone.local(2014, 10, 15)
|
104
|
+
range_end = Time.zone.local(2014, 10, 16)
|
103
105
|
range = range_start..range_end
|
104
106
|
Article.data_for(:views, interval: :day, range: range)
|
105
107
|
# => [
|
@@ -111,6 +113,7 @@ Article.data_for(:views, interval: :day, range: range)
|
|
111
113
|
## Limitations
|
112
114
|
|
113
115
|
- It works *ONLY* with *PostgreSQL* at the moment.
|
116
|
+
- Ruby 2+
|
114
117
|
- ActiveRecord 3+
|
115
118
|
- ActiveSupport 3+
|
116
119
|
- It's polymorphic association.
|
@@ -142,9 +145,9 @@ class CreateEventCounters < ActiveRecord::Migration
|
|
142
145
|
t.datetime :created_at
|
143
146
|
end
|
144
147
|
|
145
|
-
add_index :event_counters, :
|
148
|
+
add_index :event_counters, :created_at
|
146
149
|
add_index :event_counters,
|
147
|
-
[:countable_type, :name, :countable_id], name: '
|
150
|
+
[:countable_type, :name, :countable_id], name: 'index_complex'
|
148
151
|
|
149
152
|
end
|
150
153
|
|
data/lib/event_counter.rb
CHANGED
@@ -27,7 +27,7 @@ class EventCounter < ActiveRecord::Base
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def self.make(val = 1, on_time: nil, force: false)
|
30
|
-
on_time = normalize_on_time(on_time)
|
30
|
+
on_time = normalize_on_time!(on_time)
|
31
31
|
|
32
32
|
attrs = { created_at: on_time }
|
33
33
|
|
@@ -52,7 +52,7 @@ class EventCounter < ActiveRecord::Base
|
|
52
52
|
|
53
53
|
val ||= 1
|
54
54
|
|
55
|
-
on_time = normalize_on_time(on_time)
|
55
|
+
on_time = normalize_on_time!(on_time)
|
56
56
|
|
57
57
|
counter = where(created_at: on_time).first
|
58
58
|
|
@@ -87,8 +87,11 @@ class EventCounter < ActiveRecord::Base
|
|
87
87
|
fail CounterError, args
|
88
88
|
end
|
89
89
|
|
90
|
-
def self.normalize_on_time(on_time)
|
90
|
+
def self.normalize_on_time!(on_time)
|
91
91
|
on_time ||= Time.zone.now
|
92
|
+
|
93
|
+
counter_error!(:time_zone) unless on_time.is_a?(ActiveSupport::TimeWithZone)
|
94
|
+
|
92
95
|
on_time =
|
93
96
|
case current_interval
|
94
97
|
when Symbol
|
@@ -108,7 +111,9 @@ class EventCounter < ActiveRecord::Base
|
|
108
111
|
less: 'Specified interval (%{interval}) could not be less then ' \
|
109
112
|
'a defined (%{default_interval}) in a countable model (%{model}).',
|
110
113
|
multiple: 'Specified interval (%{interval}) should be a multiple of ' \
|
111
|
-
'a defined (%{default_interval}) in a countable model (%{model}).'
|
114
|
+
'a defined (%{default_interval}) in a countable model (%{model}).',
|
115
|
+
time_zone: 'The :on_time option should be defined with time zone, e.x.: ' \
|
116
|
+
'Time.zone.local(2014, 1, 1, 1, 1)'
|
112
117
|
}
|
113
118
|
|
114
119
|
attr_accessor :extra
|
@@ -27,7 +27,7 @@ describe EventCounter do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
it '#make on time' do
|
30
|
-
on_time = Time.
|
30
|
+
on_time = Time.zone.local(2014, 1, 1, 1, 14)
|
31
31
|
expect {
|
32
32
|
counter = ball.rotations.make(
|
33
33
|
3, on_time: on_time)
|
@@ -48,7 +48,7 @@ describe EventCounter do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
it '#make on time with interval as symbol' do
|
51
|
-
on_time = Time.
|
51
|
+
on_time = Time.zone.local(2014, 1, 1, 1, 1)
|
52
52
|
[:week, :month, :year].each do |interval|
|
53
53
|
expect {
|
54
54
|
counter = ball.send(:"rotations_by_#{interval}").make(
|
@@ -80,13 +80,13 @@ describe Ball do
|
|
80
80
|
expect(ball.up!(:rotations)).to be_a(EventCounter)
|
81
81
|
}.to change { EventCounter.count }.by(1)
|
82
82
|
|
83
|
-
on_time = Time.
|
83
|
+
on_time = Time.zone.local(2011, 11, 11, 11, 11)
|
84
84
|
expect {
|
85
85
|
expect(ball.up!(:rotations, on_time: on_time))
|
86
86
|
.to be_a(EventCounter)
|
87
87
|
}.to change { EventCounter.count }.by(1)
|
88
88
|
|
89
|
-
on_time = Time.
|
89
|
+
on_time = Time.zone.local(2012, 12, 12, 12, 12)
|
90
90
|
expect {
|
91
91
|
expect(ball.up!(:rotations, 5, on_time: on_time))
|
92
92
|
.to be_a(EventCounter)
|
@@ -98,13 +98,13 @@ describe Ball do
|
|
98
98
|
expect(ball.down!(:rotations)).to be_a(EventCounter)
|
99
99
|
}.to change { EventCounter.count }.by(1)
|
100
100
|
|
101
|
-
on_time = Time.
|
101
|
+
on_time = Time.zone.local(2011, 11, 11, 11, 11)
|
102
102
|
expect {
|
103
103
|
expect(ball.down!(:rotations, on_time: on_time))
|
104
104
|
.to be_a(EventCounter)
|
105
105
|
}.to change { EventCounter.count }.by(1)
|
106
106
|
|
107
|
-
on_time = Time.
|
107
|
+
on_time = Time.zone.local(2012, 12, 12, 12, 12)
|
108
108
|
expect {
|
109
109
|
expect(ball.down!(:rotations, 5, on_time: on_time))
|
110
110
|
.to be_a(EventCounter)
|
@@ -152,7 +152,7 @@ describe Ball do
|
|
152
152
|
end
|
153
153
|
|
154
154
|
it 'increments existent counter on time with default value' do
|
155
|
-
on_time = Time.
|
155
|
+
on_time = Time.zone.local(2012, 12, 12, 12, 12)
|
156
156
|
counter = ball.rotations.make on_time: on_time
|
157
157
|
|
158
158
|
expect {
|
@@ -163,7 +163,7 @@ describe Ball do
|
|
163
163
|
end
|
164
164
|
|
165
165
|
it 'decrements existent counter on time with default value' do
|
166
|
-
on_time = Time.
|
166
|
+
on_time = Time.zone.local(2012, 12, 12, 12, 12)
|
167
167
|
counter = ball.rotations.make on_time: on_time
|
168
168
|
|
169
169
|
expect {
|
@@ -174,7 +174,7 @@ describe Ball do
|
|
174
174
|
end
|
175
175
|
|
176
176
|
it 'increments existent counter on time with specified value' do
|
177
|
-
on_time = Time.
|
177
|
+
on_time = Time.zone.local(2012, 12, 12, 12, 12)
|
178
178
|
counter = ball.rotations.make 2, on_time: on_time
|
179
179
|
|
180
180
|
expect {
|
@@ -185,7 +185,7 @@ describe Ball do
|
|
185
185
|
end
|
186
186
|
|
187
187
|
it 'decrements existent counter on time with specified value' do
|
188
|
-
on_time = Time.
|
188
|
+
on_time = Time.zone.local(2012, 12, 12, 12, 12)
|
189
189
|
counter = ball.rotations.make 2, on_time: on_time
|
190
190
|
|
191
191
|
expect {
|
@@ -207,7 +207,7 @@ describe Ball do
|
|
207
207
|
end
|
208
208
|
|
209
209
|
it 'forces existent counter on time with new value' do
|
210
|
-
on_time = Time.
|
210
|
+
on_time = Time.zone.local(2012, 12, 12, 12, 12)
|
211
211
|
counter = ball.rotations.make 2, on_time: on_time
|
212
212
|
|
213
213
|
expect {
|
@@ -230,7 +230,7 @@ describe Ball do
|
|
230
230
|
|
231
231
|
def setup_counters(countable_count = 1)
|
232
232
|
[1, 1, 2, 3, 5, 8, 13, 21, 34].each do |n|
|
233
|
-
on_time = Time.
|
233
|
+
on_time = Time.zone.local(2014, 1, 1, 1, n)
|
234
234
|
if countable_count == 1
|
235
235
|
ball.rotations.make n, on_time: on_time
|
236
236
|
else
|
@@ -282,8 +282,8 @@ describe Ball do
|
|
282
282
|
end
|
283
283
|
|
284
284
|
it 'with a greater interval and a time range' do
|
285
|
-
range_start = Time.
|
286
|
-
range_end = Time.
|
285
|
+
range_start = Time.zone.local 2014, 1, 1, 1, 15
|
286
|
+
range_end = Time.zone.local 2014, 1, 1, 1, 45
|
287
287
|
range = range_start.in_time_zone..range_end.in_time_zone
|
288
288
|
|
289
289
|
data = [ [ 10, 13 ], [ 20, 21 ], [ 30, 34 ], [ 40, 0] ]
|
@@ -293,7 +293,7 @@ describe Ball do
|
|
293
293
|
end
|
294
294
|
|
295
295
|
it 'with a greater interval as symbol' do
|
296
|
-
beginning_of_week = Time.
|
296
|
+
beginning_of_week = Time.zone.local(2014).beginning_of_week
|
297
297
|
|
298
298
|
data = [ [ beginning_of_week, 88 ] ]
|
299
299
|
|
@@ -333,8 +333,8 @@ describe Ball do
|
|
333
333
|
it 'with a greater interval within range' do
|
334
334
|
data = [ [ 10, 39 ], [ 20, 63 ] ]
|
335
335
|
|
336
|
-
range_start = Time.
|
337
|
-
range_end = Time.
|
336
|
+
range_start = Time.zone.local(2014, 1, 1, 1, 15)
|
337
|
+
range_end = Time.zone.local(2014, 1, 1, 1, 29)
|
338
338
|
range = range_start..range_end
|
339
339
|
|
340
340
|
expect(subject.data_for(:rotations, interval: 10.minutes, range: range))
|
@@ -342,7 +342,7 @@ describe Ball do
|
|
342
342
|
end
|
343
343
|
|
344
344
|
it 'with a greater interval as symbol and a simple data' do
|
345
|
-
bmonth = Time.
|
345
|
+
bmonth = Time.zone.local(2014, 1, 1).beginning_of_month
|
346
346
|
data = [ [ bmonth, 264 ] ]
|
347
347
|
|
348
348
|
expect(subject.data_for(:rotations, interval: :month))
|
@@ -350,7 +350,7 @@ describe Ball do
|
|
350
350
|
end
|
351
351
|
|
352
352
|
it 'with a greater interval as symbol and a simple data within range' do
|
353
|
-
bmonth = Time.
|
353
|
+
bmonth = Time.zone.local(2014, 1, 1).beginning_of_month
|
354
354
|
data = [ [ bmonth, 264 ] ]
|
355
355
|
|
356
356
|
range_start = bmonth
|
@@ -372,8 +372,7 @@ describe Ball do
|
|
372
372
|
end
|
373
373
|
end
|
374
374
|
|
375
|
-
data = (6..12).map { |x| [ Time.
|
376
|
-
|
375
|
+
data = (6..12).map { |x| [ Time.zone.local(2013, x), 264 ] }
|
377
376
|
range_start = data[0][0].beginning_of_month
|
378
377
|
range_end = data[-1][0].end_of_month
|
379
378
|
range = range_start..range_end
|
@@ -7,8 +7,8 @@ describe Ball, slow: true do
|
|
7
7
|
DatabaseCleaner.clean_with(:truncation)
|
8
8
|
end
|
9
9
|
|
10
|
-
let(:range_start) {
|
11
|
-
let(:range_end) {
|
10
|
+
let(:range_start) { Time.zone.local(2013, 7).beginning_of_month }
|
11
|
+
let(:range_end) { Time.zone.local(2014, 6).end_of_month }
|
12
12
|
let(:range) { range_start..range_end }
|
13
13
|
|
14
14
|
def disable_logging(&blk)
|
@@ -27,7 +27,7 @@ describe Ball, slow: true do
|
|
27
27
|
|
28
28
|
ball = Ball.create!
|
29
29
|
|
30
|
-
(Time.
|
30
|
+
(Time.zone.local(2012).to_i..Time.zone.local(2015).to_i).step(step) do |i|
|
31
31
|
on_time = Time.at(i)
|
32
32
|
ball.rotations.make on_time: on_time
|
33
33
|
end
|
data/spec/support/matchers.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: event-counter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anton Orel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|