minuteman 1.0.3 → 2.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gems +3 -0
- data/.travis.yml +4 -3
- data/ORIGIN.md +21 -0
- data/README.md +115 -122
- data/Rakefile +3 -3
- data/SPEC.md +21 -0
- data/lib/minuteman.rb +88 -122
- data/lib/minuteman/analyzable.rb +96 -0
- data/lib/minuteman/analyzer.rb +21 -0
- data/lib/minuteman/configuration.rb +25 -0
- data/lib/minuteman/counter.rb +21 -0
- data/lib/minuteman/event.rb +12 -0
- data/lib/minuteman/lua/operations.lua +37 -0
- data/lib/minuteman/model.rb +36 -0
- data/lib/minuteman/result.rb +12 -0
- data/lib/minuteman/trigger.rb +4 -0
- data/lib/minuteman/user.rb +38 -0
- data/minuteman.gemspec +4 -5
- data/test/helper.rb +2 -0
- data/test/minuteman_bench.rb +72 -0
- data/test/minuteman_test.rb +204 -0
- metadata +44 -73
- data/Gemfile +0 -4
- data/Gemfile.lock +0 -30
- data/lib/minuteman/bit_operations.rb +0 -97
- data/lib/minuteman/bit_operations/data.rb +0 -33
- data/lib/minuteman/bit_operations/operation.rb +0 -115
- data/lib/minuteman/bit_operations/plain.rb +0 -34
- data/lib/minuteman/bit_operations/result.rb +0 -15
- data/lib/minuteman/bit_operations/with_data.rb +0 -56
- data/lib/minuteman/keys_methods.rb +0 -23
- data/lib/minuteman/time_events.rb +0 -18
- data/lib/minuteman/time_span.rb +0 -36
- data/lib/minuteman/time_spans.rb +0 -7
- data/lib/minuteman/time_spans/day.rb +0 -17
- data/lib/minuteman/time_spans/hour.rb +0 -19
- data/lib/minuteman/time_spans/minute.rb +0 -19
- data/lib/minuteman/time_spans/month.rb +0 -17
- data/lib/minuteman/time_spans/week.rb +0 -18
- data/lib/minuteman/time_spans/year.rb +0 -17
- data/test/bench/minuteman_bench.rb +0 -37
- data/test/test_helper.rb +0 -9
- data/test/unit/minuteman_test.rb +0 -225
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 33273982b184b97986adee038d64bc71a5ebf868
|
4
|
+
data.tar.gz: 1787e29f6314d78e1967140a1194692b58fc678c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8e3d61fa6e931eceb2935d14ca8d734494e945e04d7a8676565e8c1c5e47454cfffdc336d71724e9c05ccfa2ac17e4f79fe69c4d4054bb1223988653a63c9d2a
|
7
|
+
data.tar.gz: 4925693e4ed12b00efe943693c0940296eb6c7d762e5a8697be551381ce0711b1feee081e778867f7a3c1d24db99c914c3a13da7cd0b9f69acb77ea9f3af9119
|
data/.gems
ADDED
data/.travis.yml
CHANGED
data/ORIGIN.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Origin
|
2
|
+
|
3
|
+
_Freenode - #cuba.rb - 2012/10/30 15:20 UYT_
|
4
|
+
|
5
|
+
> **conanbatt:** anyone here knows some good web app metrics tool ?
|
6
|
+
|
7
|
+
> **conanbatt:** i use google analytics for the page itself, and its good, but for the webapp its really not useful
|
8
|
+
|
9
|
+
> **tizoc: conanbatt:** http://amix.dk/blog/post/19714 you can port this (if an equivalent doesn't exist already)
|
10
|
+
|
11
|
+
> **conanbatt:** the metrics link is excellent but its python and released 5 days ago lol
|
12
|
+
|
13
|
+
> **elcuervo: tizoc:** the idea it's awesome
|
14
|
+
|
15
|
+
> **elcuervo:** interesting...
|
16
|
+
|
17
|
+
## Inspiration
|
18
|
+
|
19
|
+
* http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/
|
20
|
+
* http://amix.dk/blog/post/19714
|
21
|
+
* http://en.wikipedia.org/wiki/Bit_array
|
data/README.md
CHANGED
@@ -2,172 +2,165 @@
|
|
2
2
|
|
3
3
|
# Minuteman
|
4
4
|
[![Code Climate](https://codeclimate.com/github/elcuervo/minuteman.png)](https://codeclimate.com/github/elcuervo/minuteman)
|
5
|
-
[![Build Status](https://secure.travis-ci.org/elcuervo/minuteman.png?branch=master)](https://travis-ci.org/elcuervo/minuteman)
|
6
5
|
|
7
|
-
|
6
|
+
[![Build Status](https://travis-ci.org/elcuervo/minuteman.svg)](https://travis-ci.org/elcuervo/minuteman)
|
7
|
+
|
8
|
+
> Minutemen were members of teams from Massachusetts that were well-prepared
|
8
9
|
militia companies of select men from the American colonial partisan militia
|
9
10
|
during the American Revolutionary War. _They provided a highly mobile, rapidly
|
10
11
|
deployed force that allowed the colonies to respond immediately to war threats,
|
11
12
|
hence the name._
|
12
13
|
|
13
|
-
## Origin
|
14
|
-
Freenode - #cuba.rb - 2012/10/30 15:20 UYT
|
15
|
-
|
16
|
-
**conanbatt:** anyone here knows some good web app metrics tool ?
|
17
|
-
|
18
|
-
**conanbatt:** i use google analytics for the page itself, and its good, but for the webapp its really not useful
|
19
|
-
|
20
|
-
**tizoc: conanbatt:** http://amix.dk/blog/post/19714 you can port this (if an equivalent doesn't exist already)
|
21
|
-
|
22
|
-
**conanbatt:** the metrics link is excellent but its python and released 5 days ago lol
|
23
|
-
|
24
|
-
**elcuervo: tizoc:** the idea it's awesome
|
25
|
-
|
26
|
-
**elcuervo:** interesting...
|
27
|
-
|
28
|
-
|
29
|
-
## Inspiration
|
30
|
-
|
31
|
-
* http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/
|
32
|
-
* http://amix.dk/blog/post/19714
|
33
|
-
* http://en.wikipedia.org/wiki/Bit_array
|
34
|
-
|
35
14
|
## Installation
|
36
15
|
|
37
|
-
### Important!
|
38
|
-
|
39
|
-
Depends on Redis 2.6 for the `bitop` operation. You can install it using:
|
40
|
-
|
41
|
-
```bash
|
42
|
-
brew install redis
|
43
|
-
```
|
44
|
-
|
45
|
-
or upgrading your current version:
|
46
|
-
|
47
|
-
```bash
|
48
|
-
brew upgrade redis
|
49
|
-
```
|
50
|
-
|
51
|
-
And then install the gem
|
52
|
-
|
53
16
|
```bash
|
54
17
|
gem install minuteman
|
55
18
|
```
|
56
19
|
|
57
|
-
|
58
|
-
|
59
|
-
Currently Minutemen supports two options `:silent (default: false)` and `:redis
|
60
|
-
(default: {})`
|
20
|
+
### Configuration
|
61
21
|
|
62
|
-
|
22
|
+
Configuration exists within the `config` block:
|
63
23
|
|
64
|
-
|
24
|
+
```ruby
|
25
|
+
Minuteman.configure do |config|
|
26
|
+
# You need to use Redic to define a new Redis connection
|
27
|
+
config.redis = Redic.new("redis://127.0.0.1:6379/1")
|
28
|
+
|
29
|
+
# The prefix affects operations
|
30
|
+
config.prefix = "Tomato"
|
31
|
+
|
32
|
+
# The patterns is what Minuteman uses for the tracking/counting and the
|
33
|
+
# different analyzers
|
34
|
+
config.patterns = {
|
35
|
+
dia: -> (time) { time.strftime("%Y-%m-%d") }
|
36
|
+
}
|
37
|
+
end
|
38
|
+
```
|
65
39
|
|
66
|
-
|
67
|
-
day]` will only track events on that timespans. Ignoring the rest
|
40
|
+
## Tracking
|
68
41
|
|
69
|
-
|
70
|
-
connection already established (`Redis::Namespace` works as well).
|
42
|
+
Tracking is the most basic scenario for Minuteman:
|
71
43
|
|
72
44
|
```ruby
|
73
|
-
|
45
|
+
# This will create the "landing:new" event in all the defined patterns and since
|
46
|
+
# there is no user here it will create an annonymous one.
|
47
|
+
# This user only exists in the Minuteman context.
|
48
|
+
user = Minuteman.track("landing:new")
|
74
49
|
|
75
|
-
#
|
76
|
-
|
50
|
+
# The id it's an internal representation, not useful for you
|
51
|
+
user.id # => "1"
|
77
52
|
|
78
|
-
#
|
79
|
-
|
53
|
+
# This is the unique id. With this you can have an identifier for the user
|
54
|
+
user.uid # => "787c8770-0ac2-4654-9fa4-e57d152fa341"
|
80
55
|
|
81
|
-
#
|
82
|
-
|
83
|
-
analytics.track("login:successful", other_user.id)
|
56
|
+
# You can use the `user` to keep tracking things:
|
57
|
+
user.track("register:page")
|
84
58
|
|
85
|
-
#
|
86
|
-
|
59
|
+
# Or use it as an argument
|
60
|
+
Minuteman.track("help:page", user)
|
87
61
|
|
88
|
-
#
|
89
|
-
|
62
|
+
# Or track several users at once
|
63
|
+
Minuteman.track("help:page", [user1, user2, user3])
|
90
64
|
|
91
|
-
#
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
analytics.day("login:successful")
|
96
|
-
analytics.hour("login:successful")
|
97
|
-
analytics.minute("login:successful")
|
98
|
-
|
99
|
-
# Lists all the tracked events
|
100
|
-
analytics.events
|
101
|
-
#=> ["login:successful", "programming:login:ruby"]
|
65
|
+
# By default all the tracking and counting events are triggered with `Time.now.utc`
|
66
|
+
# but you can change that as well:
|
67
|
+
Minuteman.track("setup:account", user, Time.new(2010, 2, 10))
|
68
|
+
```
|
102
69
|
|
103
|
-
|
104
|
-
today_events.length
|
105
|
-
#=> 2
|
70
|
+
## Analysis
|
106
71
|
|
107
|
-
|
108
|
-
today_events.include?(user.id)
|
109
|
-
#=> true
|
110
|
-
today_events.include?(admin.id)
|
111
|
-
#=> false
|
72
|
+
There is a powerful engine behind all the operations which is Redis + Lua <3
|
112
73
|
|
113
|
-
|
114
|
-
|
115
|
-
|
74
|
+
```ruby
|
75
|
+
# The analysis of information relies on `Minuteman.patterns` and if you don't
|
76
|
+
# change it you'll get acess to `year`, `month`, `day`, `hour`, `minute`.
|
77
|
+
# To get information about `register:page` for today:
|
78
|
+
Minuteman.analyze("register:page").day
|
79
|
+
|
80
|
+
# You can always pass a `Time` instance to set the time you need information.
|
81
|
+
Minuteman.analyze("register:page").day(Time.new(2004, 2, 12))
|
82
|
+
|
83
|
+
# You also have a shorthand for analysis:
|
84
|
+
register_page_month = Minuteman("register:page").month
|
85
|
+
|
86
|
+
# And the power of Minuteman relies on the operations you can do with that.
|
87
|
+
# Counting the amount:
|
88
|
+
register_page_month.count # => 10
|
89
|
+
|
90
|
+
# Or knowing if a user is included in that set:
|
91
|
+
register_page_month.include?(User[42]) # => true
|
92
|
+
|
93
|
+
# But the most important part is the ability to do bit operations on that:
|
94
|
+
# You can intersect sets using bitwise AND(`&`), OR(`|`), NOT(`~`, `-`) and XOR(`^`).
|
95
|
+
# Also you can use plus(`+`) and minus(`-`) operations.
|
96
|
+
# In this example we'll get all the users that accessed our site via a promo
|
97
|
+
# invite but didn't buy anything
|
98
|
+
(
|
99
|
+
Minuteman("promo:email").day & Minuteman("promo:google").day
|
100
|
+
) - Minuteman("buy:success").day
|
116
101
|
```
|
117
102
|
|
118
|
-
##
|
103
|
+
## Counting
|
119
104
|
|
120
|
-
|
121
|
-
Also you can use plus(`+`) and minus(`-`) operations.
|
105
|
+
Since Minuteman 2.0 there's the possibility to have counters.
|
122
106
|
|
123
107
|
```ruby
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
~set1 \
|
131
|
-
|==> This are the same
|
132
|
-
-set1 /
|
133
|
-
```
|
108
|
+
# Counting works in a very similar way to tracking but with some important
|
109
|
+
# differences. Trackings are idempotent unlike countings and they do not provide
|
110
|
+
# operations between sets... you can use plain ruby for that.
|
111
|
+
# This will add 1 to the `hits:page` counter:
|
112
|
+
Minuteman.add("hits:page")
|
134
113
|
|
135
|
-
|
114
|
+
# You can also pass a `Time` instance to define when this tracking ocurred:
|
115
|
+
Minuteman.add("hits:page", Time.new(2012, 20, 01))
|
136
116
|
|
137
|
-
|
117
|
+
# And you can also send users to also count the times that given user did that
|
118
|
+
# event
|
119
|
+
Minuteman.add("hits:page", Time.new(2012, 20, 01), user)
|
138
120
|
|
139
|
-
You
|
140
|
-
|
121
|
+
# You can access counting information similar to tracking:
|
122
|
+
Minuteman.count("hits:page").day.count # => 201
|
141
123
|
|
142
|
-
|
143
|
-
|
144
|
-
payed_from_miami = paid & User.find_all_by_state("MIA").map(&:id)
|
145
|
-
payed_from_miami.size
|
146
|
-
#=> 43
|
147
|
-
payed_users_from_miami = payed_from_miami.map { |id| User.find(id) }
|
124
|
+
# Or with a shorthand:
|
125
|
+
Counterman("hits:page").day.count # => 201
|
148
126
|
```
|
149
127
|
|
150
|
-
|
128
|
+
## Users
|
151
129
|
|
152
|
-
|
130
|
+
Minuteman 2.0 adds the concept of users which can be annonymous or have a
|
131
|
+
relation with your own database.
|
153
132
|
|
154
133
|
```ruby
|
155
|
-
|
156
|
-
|
134
|
+
# This will create an annonymous user
|
135
|
+
user = Minuteman::User.create
|
157
136
|
|
158
|
-
|
159
|
-
|
137
|
+
# Users are just a part of Minuteman and do not interfere with your own.
|
138
|
+
# They do have some properties like a unique identifier you can use to find it
|
139
|
+
# in the future
|
140
|
+
user.uid # => "787c8770-0ac2-4654-9fa4-e57d152fa341"
|
160
141
|
|
161
|
-
#
|
162
|
-
|
163
|
-
|
142
|
+
# User lookup works like this:
|
143
|
+
# And you can use that unique identifier as a key in a cookie to see what your
|
144
|
+
# uses do when no one is looking
|
145
|
+
Minuteman::User['787c8770-0ac2-4654-9fa4-e57d152fa341']
|
164
146
|
|
165
|
-
|
147
|
+
# But since the point is to be able to get tied to your data you can promote a
|
148
|
+
# user, from anonymous to "real"
|
149
|
+
user.promote(123)
|
166
150
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
151
|
+
# Lookups also work with promoted ids
|
152
|
+
Minuteman::User["123"]
|
153
|
+
|
154
|
+
# Having a user you can do all the same operations minus the hussle.
|
155
|
+
# Like tracking:
|
156
|
+
user.track("user:login")
|
157
|
+
|
158
|
+
# or adding:
|
159
|
+
user.add("failed:login")
|
160
|
+
|
161
|
+
# or counting
|
162
|
+
user.count("failed:login").month.count # => 23
|
171
163
|
|
172
|
-
|
164
|
+
# But also the counted events go to the big picture
|
165
|
+
Counterman("failed:login").month.count # => 512
|
173
166
|
```
|
data/Rakefile
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require "rake/testtask"
|
2
2
|
|
3
|
-
Rake::TestTask.new("
|
3
|
+
Rake::TestTask.new("test") do |t|
|
4
|
+
t.libs << "test"
|
4
5
|
t.pattern = "test/**/*_test.rb"
|
5
6
|
end
|
6
7
|
|
7
8
|
Rake::TestTask.new("bench") do |t|
|
8
|
-
t.pattern = "test
|
9
|
+
t.pattern = "test/**/*_bench.rb"
|
9
10
|
end
|
10
11
|
|
11
12
|
task :default => [:test]
|
12
13
|
task :all => [:test, :bench]
|
13
|
-
task :test => [:spec]
|
data/SPEC.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
```ruby
|
2
|
+
# Track an event
|
3
|
+
minuteman_user = Minuteman.track("login:successfull")
|
4
|
+
minuteman_user.promote(user.id)
|
5
|
+
|
6
|
+
# Trigger an event in the pipeline
|
7
|
+
Minuteman.trigger("event:name")
|
8
|
+
|
9
|
+
# Gets an event analyzer
|
10
|
+
analyzer = Minuteman.analyze("event:name")
|
11
|
+
# Counts unique users in that given time
|
12
|
+
analyze.day(Time.now.utc)
|
13
|
+
|
14
|
+
Minuteman("event:name").day | Minuteman("event2:name).day
|
15
|
+
```
|
16
|
+
|
17
|
+
Caching:
|
18
|
+
Cache ids in events:
|
19
|
+
|
20
|
+
Minuteman::Operation:50:AND:20, Minuteman::Operation:50:OR:20
|
21
|
+
Minuteman::Operation:(50:AND:20):AND:14
|
data/lib/minuteman.rb
CHANGED
@@ -1,151 +1,117 @@
|
|
1
|
-
require
|
2
|
-
require "time"
|
3
|
-
require "forwardable"
|
4
|
-
require "minuteman/time_events"
|
1
|
+
require 'redic'
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
extend Forwardable
|
3
|
+
module Minuteman
|
4
|
+
LUA_CACHE = Hash.new { |h, k| h[k] = Hash.new }
|
5
|
+
LUA_OPERATIONS = File.expand_path("../minuteman/lua/operations.lua", __FILE__)
|
10
6
|
|
11
7
|
class << self
|
12
|
-
|
13
|
-
|
14
|
-
# Public: Prevents a fatal error if the options are set to silent
|
15
|
-
#
|
16
|
-
def safe(&block)
|
17
|
-
yield if block
|
18
|
-
rescue Redis::BaseError => e
|
19
|
-
raise e unless options[:silent]
|
8
|
+
def config
|
9
|
+
@_configuration ||= Configuration.new
|
20
10
|
end
|
21
|
-
end
|
22
|
-
|
23
|
-
PREFIX = "minuteman"
|
24
11
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
#
|
29
|
-
# options - An options hash to change how Minuteman behaves
|
30
|
-
#
|
31
|
-
def initialize(options = {})
|
32
|
-
redis_options = options.delete(:redis) || {}
|
12
|
+
def configure
|
13
|
+
yield(config)
|
14
|
+
end
|
33
15
|
|
34
|
-
|
35
|
-
|
16
|
+
def prefix
|
17
|
+
config.prefix
|
18
|
+
end
|
36
19
|
|
37
|
-
|
38
|
-
|
39
|
-
|
20
|
+
def patterns
|
21
|
+
config.patterns
|
22
|
+
end
|
40
23
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
# ids - The ids to be tracked
|
45
|
-
#
|
46
|
-
# Examples
|
47
|
-
#
|
48
|
-
# analytics = Minuteman.new
|
49
|
-
# analytics.track("login", 1)
|
50
|
-
# analytics.track("login", [2, 3, 4])
|
51
|
-
#
|
52
|
-
def track(event_name, ids, time = Time.now.utc)
|
53
|
-
event_time = time.kind_of?(Time) ? time : Time.parse(time.to_s)
|
54
|
-
time_events = TimeEvents.start(@time_spans, event_name, event_time)
|
55
|
-
|
56
|
-
track_events(time_events, Array(ids))
|
57
|
-
end
|
24
|
+
def time_spans
|
25
|
+
@_time_spans = patterns.keys
|
26
|
+
end
|
58
27
|
|
59
|
-
|
60
|
-
|
61
|
-
def events
|
62
|
-
keys = safe { redis.keys([PREFIX, "*", "????"].join("_")) }
|
63
|
-
keys.map { |key| key.split("_")[1] }
|
64
|
-
end
|
28
|
+
def track(action, users = nil, time = Time.now.utc)
|
29
|
+
users = Minuteman::User.create if users.nil?
|
65
30
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
31
|
+
Array(users).each do |user|
|
32
|
+
process do
|
33
|
+
time_spans.each do |time_span|
|
34
|
+
event = Minuteman::Event.find_or_create(
|
35
|
+
type: action,
|
36
|
+
time: patterns[time_span].call(time)
|
37
|
+
)
|
71
38
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
safe { redis.del(keys) } if keys.any?
|
77
|
-
end
|
39
|
+
event.setbit(user.id)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
78
43
|
|
79
|
-
|
80
|
-
|
81
|
-
def reset_all
|
82
|
-
keys = safe { redis.keys([PREFIX, "*"].join("_")) }
|
83
|
-
safe { redis.del(keys) } if keys.any?
|
84
|
-
end
|
44
|
+
users
|
45
|
+
end
|
85
46
|
|
86
|
-
|
47
|
+
def add(action, time = Time.now.utc, users = [])
|
48
|
+
time_spans.each do |time_span|
|
49
|
+
process do
|
50
|
+
counter = Minuteman::Counter.create({
|
51
|
+
type: action,
|
52
|
+
time: patterns[time_span].call(time)
|
53
|
+
})
|
87
54
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
#
|
92
|
-
def generate_spans(spans)
|
93
|
-
spans.map do |method_name|
|
94
|
-
constructor = self.class.const_get(method_name.capitalize)
|
55
|
+
counter.incr
|
56
|
+
end
|
57
|
+
end
|
95
58
|
|
96
|
-
|
97
|
-
|
98
|
-
|
59
|
+
Array(users).each do |user|
|
60
|
+
time_spans.each do |time_span|
|
61
|
+
counter = Minuteman::Counter::User.create({
|
62
|
+
user_id: user.id,
|
63
|
+
type: action,
|
64
|
+
time: patterns[time_span].call(time)
|
65
|
+
})
|
99
66
|
|
100
|
-
|
67
|
+
counter.incr
|
68
|
+
end
|
101
69
|
end
|
70
|
+
end
|
102
71
|
|
103
|
-
|
72
|
+
def analyze(action)
|
73
|
+
analyzers_cache[action]
|
104
74
|
end
|
105
|
-
end
|
106
75
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
{ cache: true, silent: false }
|
111
|
-
end
|
76
|
+
def count(action)
|
77
|
+
counters_cache[action]
|
78
|
+
end
|
112
79
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
object
|
122
|
-
else
|
123
|
-
Redis.new(object)
|
80
|
+
private
|
81
|
+
|
82
|
+
def process(&block)
|
83
|
+
if !!config.parallel
|
84
|
+
Thread.current(&block)
|
85
|
+
else
|
86
|
+
block.call
|
87
|
+
end
|
124
88
|
end
|
125
|
-
end
|
126
89
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
# ids: The ids to be tracked
|
131
|
-
#
|
132
|
-
def track_events(time_events, ids)
|
133
|
-
safe_multi do
|
134
|
-
time_events.each do |event|
|
135
|
-
ids.each { |id| safe { redis.setbit(event.key, id, 1) } }
|
90
|
+
def analyzers_cache
|
91
|
+
@_analyzers_cache ||= Hash.new do |h,k|
|
92
|
+
h[k] = Minuteman::Analyzer.new(k)
|
136
93
|
end
|
137
94
|
end
|
138
|
-
end
|
139
95
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
96
|
+
def counters_cache
|
97
|
+
@_counters_cache ||= Hash.new do |h,k|
|
98
|
+
h[k] = Minuteman::Analyzer.new(k, Minuteman::Counter)
|
99
|
+
end
|
100
|
+
end
|
144
101
|
end
|
102
|
+
end
|
145
103
|
|
146
|
-
|
147
|
-
|
148
|
-
def operations_cache_key_prefix
|
149
|
-
[ PREFIX, Minuteman::KeysMethods::BIT_OPERATION_PREFIX ].join("_")
|
150
|
-
end
|
104
|
+
def Minuteman(action)
|
105
|
+
Minuteman.analyze(action)
|
151
106
|
end
|
107
|
+
|
108
|
+
def Counterman(action)
|
109
|
+
Minuteman.count(action)
|
110
|
+
end
|
111
|
+
|
112
|
+
require 'minuteman/user'
|
113
|
+
require 'minuteman/event'
|
114
|
+
require 'minuteman/counter'
|
115
|
+
require 'minuteman/result'
|
116
|
+
require 'minuteman/analyzer'
|
117
|
+
require 'minuteman/configuration'
|