event-counter 0.0.1 → 0.1.0
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/.gitignore +1 -0
- data/.travis.yml +19 -0
- data/Appraisals +11 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +4 -0
- data/README.md +65 -28
- data/event-counter.gemspec +2 -7
- data/gemfiles/pg_ar_30.gemfile +12 -0
- data/gemfiles/pg_ar_30.gemfile.lock +60 -0
- data/gemfiles/pg_ar_31.gemfile +12 -0
- data/gemfiles/pg_ar_31.gemfile.lock +60 -0
- data/gemfiles/pg_ar_32.gemfile +12 -0
- data/gemfiles/pg_ar_32.gemfile.lock +60 -0
- data/gemfiles/pg_ar_40.gemfile +12 -0
- data/gemfiles/pg_ar_40.gemfile.lock +65 -0
- data/gemfiles/pg_ar_41.gemfile +12 -0
- data/gemfiles/pg_ar_41.gemfile.lock +65 -0
- data/lib/event_counter.rb +18 -6
- data/lib/event_counter/active_record_extension.rb +101 -85
- data/lib/event_counter/version.rb +1 -1
- data/log/.gitkeep +0 -0
- data/spec/fixtures/.gitkeep +0 -0
- data/spec/lib/event_counter_spec.rb +61 -21
- data/spec/lib/performance_spec.rb +82 -31
- data/spec/spec_helper.rb +10 -13
- data/spec/support/matchers.rb +6 -4
- metadata +26 -68
- data/spec/support/fabrications.rb +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ed77b0f7b2996138e3c7125f506022dbfb1b4f6
|
4
|
+
data.tar.gz: 703501bc075661a7ef2584740ec9163450a591ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d71bb461d356f61d8c0afd1718886e0e2be6b507ea1e0994e95b25c2370495921a14167d75a4e702730a8dac9ce5a5daeb2fc759c553e0f9a6265a68fdf2b4a0
|
7
|
+
data.tar.gz: aa7d2d7006bee6837fc7fd8440fa11f5e38148e7e478024f1a25f10285cbe3808c5558d0c5e1ab0c7ad8731371545021460293155339851b2e51cb976b759559
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 1.9.3
|
4
|
+
- 2.0.0
|
5
|
+
- 2.1.0
|
6
|
+
|
7
|
+
gemfile:
|
8
|
+
- gemfiles/pg_ar_30.gemfile
|
9
|
+
- gemfiles/pg_ar_31.gemfile
|
10
|
+
- gemfiles/pg_ar_32.gemfile
|
11
|
+
- gemfiles/pg_ar_40.gemfile
|
12
|
+
|
13
|
+
script: RUN_ALL=true rspec spec
|
14
|
+
|
15
|
+
services:
|
16
|
+
- postgresql
|
17
|
+
|
18
|
+
before_script:
|
19
|
+
- psql -c 'create database event_counter_test;' -U postgres
|
data/Appraisals
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
%w(3.0 3.1 3.2 4.0 4.1).each do |ar_version|
|
2
|
+
%w(pg).each do |db_type|
|
3
|
+
appraise "#{db_type}-ar-#{ar_version.split('.').first(2).join}" do
|
4
|
+
gem 'activerecord', "~> #{ar_version}"
|
5
|
+
gem 'activesupport', "~> #{ar_version}"
|
6
|
+
gem 'database_cleaner'
|
7
|
+
gem 'pg'
|
8
|
+
gem 'rspec'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/CHANGELOG.md
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
EventCounter
|
2
|
-
===============
|
1
|
+
# EventCounter
|
3
2
|
|
4
3
|
EventCounter is a database based event counter with throttling per time intervals.
|
5
4
|
|
6
|
-
Usage
|
7
|
-
-----
|
5
|
+
## Usage
|
8
6
|
|
9
7
|
Let's define counters in model
|
10
8
|
|
@@ -23,66 +21,105 @@ Let's count...
|
|
23
21
|
article = Article.create!
|
24
22
|
|
25
23
|
article.up!(:views)
|
26
|
-
#
|
27
|
-
|
24
|
+
# => #<EventCounter id: 1, name: "views", value: 1, countable_id: 1,
|
25
|
+
# countable_type: "Article", created_at: "2014-10-16 23:20:00">
|
26
|
+
# creates counter (if it doesn't exist) with value 1 and on Time.now() rounded
|
27
|
+
# to 5 minutes, e.x.:
|
28
28
|
|
29
29
|
# at once
|
30
30
|
article.up!(:views, 3)
|
31
|
-
|
32
|
-
#
|
31
|
+
# => #<EventCounter id: 1, name: "views", value: 4, countable_id: 1,
|
32
|
+
# countable_type: "Article", created_at: "2014-10-16 23:20:00">
|
33
|
+
# Updates counter (if the other exists in that interval) with value 3 and
|
34
|
+
# on Time.now() rounded to 5 minutes
|
33
35
|
|
34
36
|
# later
|
35
37
|
article.up!(:views, 5)
|
36
|
-
|
38
|
+
# => #<EventCounter id: 2, name: "views", value: 5, countable_id: 1,
|
39
|
+
# countable_type: "Article", created_at: "2014-10-16 23:25:00">
|
37
40
|
article.down!(:views, 2)
|
38
|
-
|
41
|
+
# => #<EventCounter id: 2, name: "views", value: 3, countable_id: 1,
|
42
|
+
# countable_type: "Article", created_at: "2014-10-16 23:25:00">
|
39
43
|
|
40
44
|
# anytime or in a background job
|
41
|
-
article.up!(:views, 7, on_time: 10.minutes.ago)
|
42
|
-
|
45
|
+
article.up!(:views, 7, on_time: 10.minutes.ago.in_time_zone)
|
46
|
+
# => #<EventCounter id: 3, name: "views", value: 7, countable_id: 1,
|
47
|
+
# countable_type: "Article", created_at: "2014-10-16 23:15:00">
|
43
48
|
|
44
49
|
# we have not got? let's fix it
|
45
|
-
article.up!(:views, 9, on_time: 10.minutes.ago, force: true)
|
46
|
-
|
50
|
+
article.up!(:views, 9, on_time: 10.minutes.ago.in_time_zone, force: true)
|
51
|
+
# => #<EventCounter id: 3, name: "views", value: 9, countable_id: 1,
|
52
|
+
# countable_type: "Article", created_at: "2014-10-16 23:15:00">
|
47
53
|
```
|
48
54
|
|
49
55
|
Let's get some statistics for our charts...
|
50
56
|
|
51
57
|
```ruby
|
52
58
|
article.data_for(:views)
|
53
|
-
|
59
|
+
# => [
|
60
|
+
# [Thu, 16 Oct 2014 23:15:00 MSK +04:00, 9],
|
61
|
+
# [Thu, 16 Oct 2014 23:20:00 MSK +04:00, 4],
|
62
|
+
# [Thu, 16 Oct 2014 23:25:00 MSK +04:00, 3]
|
63
|
+
# ]
|
54
64
|
|
55
65
|
article.data_for(:views, interval: 10.minutes)
|
56
|
-
|
57
|
-
|
58
|
-
|
66
|
+
# => [
|
67
|
+
# [Thu, 16 Oct 2014 23:10:00 MSK +04:00, 9],
|
68
|
+
# [Thu, 16 Oct 2014 23:20:00 MSK +04:00, 7]
|
69
|
+
# ]
|
70
|
+
|
71
|
+
# with range
|
72
|
+
range_start = Time.mktime(2014, 10, 16, 23, 0).in_time_zone
|
73
|
+
range_end = Time.mktime(2014, 10, 16, 23, 10).in_time_zone
|
74
|
+
range = range_start..range_end
|
59
75
|
article.data_for(:views, interval: 10.minutes, range: range)
|
60
|
-
#=> [
|
76
|
+
#=> [
|
77
|
+
# [Thu, 16 Oct 2014 23:00:00 MSK +04:00, 0]
|
78
|
+
# [Thu, 16 Oct 2014 23:10:00 MSK +04:00, 9]
|
79
|
+
# ]
|
80
|
+
|
81
|
+
# for different time zone (although we have no data for that time)
|
82
|
+
range_start = Time.mktime(2014, 10, 16, 23, 0).in_time_zone('UTC')
|
83
|
+
range_end = Time.mktime(2014, 10, 16, 23, 10).in_time_zone('UTC')
|
84
|
+
range = range_start..range_end
|
85
|
+
article.data_for(:views, interval: 10.minutes, range: range, tz: 'UTC')
|
86
|
+
#=> [
|
87
|
+
# [Thu, 16 Oct 2014 23:00:00 UTC +00:00, 0]
|
88
|
+
# [Thu, 16 Oct 2014 23:10:00 UTC +00:00, 0]
|
89
|
+
# ]
|
61
90
|
|
62
91
|
article.data_for(:views, interval: :day)
|
63
|
-
|
92
|
+
# => [Thu, 16 Oct 2014 00:00:00 MSK +04:00, 16]
|
64
93
|
|
65
94
|
article.data_for(:views, interval: :day, raw: true)
|
66
|
-
#=> [{"created_at" => "2014-10-16 00:00:00
|
67
|
-
# raw result will make difference in performance on a big data
|
95
|
+
#=> [{"created_at" => "2014-10-16 00:00:00", "value" => "16"}]
|
96
|
+
# The raw result will make difference in performance on a big data.
|
97
|
+
# The returned time is in the requested time zone. By default, a normalization
|
98
|
+
# looks as `Time.zone.parse(i['created_at']), i['value'].to_i ]`
|
68
99
|
|
69
100
|
# class wide
|
70
|
-
|
101
|
+
range_start = Time.mktime(2014, 10, 15).in_time_zone
|
102
|
+
range_end = Time.mktime(2014, 10, 16).in_time_zone
|
103
|
+
range = range_start..range_end
|
71
104
|
Article.data_for(:views, interval: :day, range: range)
|
72
|
-
|
105
|
+
# => [
|
106
|
+
# [Thu, 15 Oct 2014 00:00:00 MSK +04:00, 0]
|
107
|
+
# [Thu, 16 Oct 2014 00:00:00 MSK +04:00, 16]
|
108
|
+
# ]
|
73
109
|
```
|
74
110
|
|
75
|
-
Limitations
|
76
|
-
-----------
|
111
|
+
## Limitations
|
77
112
|
|
78
113
|
- It works *ONLY* with *PostgreSQL* at the moment.
|
79
114
|
- ActiveRecord 3+
|
115
|
+
- ActiveSupport 3+
|
80
116
|
- It's polymorphic association.
|
117
|
+
- It uses ActiveSupport::TimeWithZone to return user friendly statistics.
|
118
|
+
So, you have to operate with dates with time zones.
|
81
119
|
- Use it in production with caution because it's early release.
|
82
120
|
|
83
121
|
|
84
|
-
Installation
|
85
|
-
--------------
|
122
|
+
## Installation
|
86
123
|
|
87
124
|
Add gem to Gemfile
|
88
125
|
|
data/event-counter.gemspec
CHANGED
@@ -18,12 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(/^(test|spec|features)\//)
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_dependency 'activerecord', '
|
21
|
+
spec.add_dependency 'activerecord', '>= 3'
|
22
|
+
spec.add_dependency 'activesupport', '>= 3'
|
22
23
|
spec.add_dependency 'pg', '~> 0'
|
23
|
-
|
24
|
-
spec.add_development_dependency 'bundler', '~> 1.7'
|
25
|
-
spec.add_development_dependency 'database_cleaner', '~> 0'
|
26
|
-
spec.add_development_dependency 'rspec', '~> 3'
|
27
|
-
spec.add_development_dependency 'fabrication', '~> 0'
|
28
|
-
spec.add_development_dependency 'rake', '~> 10.0'
|
29
24
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../
|
3
|
+
specs:
|
4
|
+
event-counter (0.1.0)
|
5
|
+
activerecord (>= 3)
|
6
|
+
activesupport (>= 3)
|
7
|
+
pg (~> 0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activemodel (3.2.19)
|
13
|
+
activesupport (= 3.2.19)
|
14
|
+
builder (~> 3.0.0)
|
15
|
+
activerecord (3.2.19)
|
16
|
+
activemodel (= 3.2.19)
|
17
|
+
activesupport (= 3.2.19)
|
18
|
+
arel (~> 3.0.2)
|
19
|
+
tzinfo (~> 0.3.29)
|
20
|
+
activesupport (3.2.19)
|
21
|
+
i18n (~> 0.6, >= 0.6.4)
|
22
|
+
multi_json (~> 1.0)
|
23
|
+
appraisal (1.0.2)
|
24
|
+
bundler
|
25
|
+
rake
|
26
|
+
thor (>= 0.14.0)
|
27
|
+
arel (3.0.3)
|
28
|
+
builder (3.0.4)
|
29
|
+
database_cleaner (1.3.0)
|
30
|
+
diff-lcs (1.2.5)
|
31
|
+
i18n (0.6.11)
|
32
|
+
multi_json (1.10.1)
|
33
|
+
pg (0.17.1)
|
34
|
+
rake (10.3.2)
|
35
|
+
rspec (3.1.0)
|
36
|
+
rspec-core (~> 3.1.0)
|
37
|
+
rspec-expectations (~> 3.1.0)
|
38
|
+
rspec-mocks (~> 3.1.0)
|
39
|
+
rspec-core (3.1.7)
|
40
|
+
rspec-support (~> 3.1.0)
|
41
|
+
rspec-expectations (3.1.2)
|
42
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
43
|
+
rspec-support (~> 3.1.0)
|
44
|
+
rspec-mocks (3.1.3)
|
45
|
+
rspec-support (~> 3.1.0)
|
46
|
+
rspec-support (3.1.2)
|
47
|
+
thor (0.19.1)
|
48
|
+
tzinfo (0.3.41)
|
49
|
+
|
50
|
+
PLATFORMS
|
51
|
+
ruby
|
52
|
+
|
53
|
+
DEPENDENCIES
|
54
|
+
activerecord (~> 3.0)
|
55
|
+
activesupport (~> 3.0)
|
56
|
+
appraisal
|
57
|
+
database_cleaner
|
58
|
+
event-counter!
|
59
|
+
pg
|
60
|
+
rspec
|
@@ -0,0 +1,60 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../
|
3
|
+
specs:
|
4
|
+
event-counter (0.1.0)
|
5
|
+
activerecord (>= 3)
|
6
|
+
activesupport (>= 3)
|
7
|
+
pg (~> 0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activemodel (3.2.19)
|
13
|
+
activesupport (= 3.2.19)
|
14
|
+
builder (~> 3.0.0)
|
15
|
+
activerecord (3.2.19)
|
16
|
+
activemodel (= 3.2.19)
|
17
|
+
activesupport (= 3.2.19)
|
18
|
+
arel (~> 3.0.2)
|
19
|
+
tzinfo (~> 0.3.29)
|
20
|
+
activesupport (3.2.19)
|
21
|
+
i18n (~> 0.6, >= 0.6.4)
|
22
|
+
multi_json (~> 1.0)
|
23
|
+
appraisal (1.0.2)
|
24
|
+
bundler
|
25
|
+
rake
|
26
|
+
thor (>= 0.14.0)
|
27
|
+
arel (3.0.3)
|
28
|
+
builder (3.0.4)
|
29
|
+
database_cleaner (1.3.0)
|
30
|
+
diff-lcs (1.2.5)
|
31
|
+
i18n (0.6.11)
|
32
|
+
multi_json (1.10.1)
|
33
|
+
pg (0.17.1)
|
34
|
+
rake (10.3.2)
|
35
|
+
rspec (3.1.0)
|
36
|
+
rspec-core (~> 3.1.0)
|
37
|
+
rspec-expectations (~> 3.1.0)
|
38
|
+
rspec-mocks (~> 3.1.0)
|
39
|
+
rspec-core (3.1.7)
|
40
|
+
rspec-support (~> 3.1.0)
|
41
|
+
rspec-expectations (3.1.2)
|
42
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
43
|
+
rspec-support (~> 3.1.0)
|
44
|
+
rspec-mocks (3.1.3)
|
45
|
+
rspec-support (~> 3.1.0)
|
46
|
+
rspec-support (3.1.2)
|
47
|
+
thor (0.19.1)
|
48
|
+
tzinfo (0.3.41)
|
49
|
+
|
50
|
+
PLATFORMS
|
51
|
+
ruby
|
52
|
+
|
53
|
+
DEPENDENCIES
|
54
|
+
activerecord (~> 3.1)
|
55
|
+
activesupport (~> 3.1)
|
56
|
+
appraisal
|
57
|
+
database_cleaner
|
58
|
+
event-counter!
|
59
|
+
pg
|
60
|
+
rspec
|
@@ -0,0 +1,60 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../
|
3
|
+
specs:
|
4
|
+
event-counter (0.1.0)
|
5
|
+
activerecord (>= 3)
|
6
|
+
activesupport (>= 3)
|
7
|
+
pg (~> 0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activemodel (3.2.19)
|
13
|
+
activesupport (= 3.2.19)
|
14
|
+
builder (~> 3.0.0)
|
15
|
+
activerecord (3.2.19)
|
16
|
+
activemodel (= 3.2.19)
|
17
|
+
activesupport (= 3.2.19)
|
18
|
+
arel (~> 3.0.2)
|
19
|
+
tzinfo (~> 0.3.29)
|
20
|
+
activesupport (3.2.19)
|
21
|
+
i18n (~> 0.6, >= 0.6.4)
|
22
|
+
multi_json (~> 1.0)
|
23
|
+
appraisal (1.0.2)
|
24
|
+
bundler
|
25
|
+
rake
|
26
|
+
thor (>= 0.14.0)
|
27
|
+
arel (3.0.3)
|
28
|
+
builder (3.0.4)
|
29
|
+
database_cleaner (1.3.0)
|
30
|
+
diff-lcs (1.2.5)
|
31
|
+
i18n (0.6.11)
|
32
|
+
multi_json (1.10.1)
|
33
|
+
pg (0.17.1)
|
34
|
+
rake (10.3.2)
|
35
|
+
rspec (3.1.0)
|
36
|
+
rspec-core (~> 3.1.0)
|
37
|
+
rspec-expectations (~> 3.1.0)
|
38
|
+
rspec-mocks (~> 3.1.0)
|
39
|
+
rspec-core (3.1.7)
|
40
|
+
rspec-support (~> 3.1.0)
|
41
|
+
rspec-expectations (3.1.2)
|
42
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
43
|
+
rspec-support (~> 3.1.0)
|
44
|
+
rspec-mocks (3.1.3)
|
45
|
+
rspec-support (~> 3.1.0)
|
46
|
+
rspec-support (3.1.2)
|
47
|
+
thor (0.19.1)
|
48
|
+
tzinfo (0.3.41)
|
49
|
+
|
50
|
+
PLATFORMS
|
51
|
+
ruby
|
52
|
+
|
53
|
+
DEPENDENCIES
|
54
|
+
activerecord (~> 3.2)
|
55
|
+
activesupport (~> 3.2)
|
56
|
+
appraisal
|
57
|
+
database_cleaner
|
58
|
+
event-counter!
|
59
|
+
pg
|
60
|
+
rspec
|