prisma 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/prisma-web +0 -1
- data/lib/prisma.rb +13 -10
- data/lib/prisma/filter.rb +9 -1
- data/lib/prisma/group.rb +19 -2
- data/lib/prisma/server.rb +4 -2
- metadata +35 -3
data/bin/prisma-web
CHANGED
@@ -9,7 +9,6 @@ rescue LoadError
|
|
9
9
|
end
|
10
10
|
require 'prisma/server'
|
11
11
|
|
12
|
-
|
13
12
|
Vegas::Runner.new(Prisma::Server, 'prisma-web') do |runner, opts, app|
|
14
13
|
opts.on('-N NAMESPACE', "--namespace NAMESPACE", "set the Redis namespace") {|namespace|
|
15
14
|
runner.logger.info "Using Redis namespace '#{namespace}'"
|
data/lib/prisma.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rails/all'
|
2
2
|
require 'redis-namespace'
|
3
|
+
require 'bitset'
|
3
4
|
|
4
5
|
require 'prisma/group'
|
5
6
|
require 'prisma/railtie'
|
@@ -36,7 +37,7 @@ module Prisma
|
|
36
37
|
# Configure prisma. Example usage:
|
37
38
|
# Prisma.setup do |config|
|
38
39
|
# config.group :active_api_clients { |controller| controller.current_client.id }
|
39
|
-
# config.redis = Redis.new(:
|
40
|
+
# config.redis = Redis.new(db: 1)
|
40
41
|
# config.redis_namespace = 'stats'
|
41
42
|
# config.redis_expiration_duration = 2.days
|
42
43
|
# end
|
@@ -47,15 +48,15 @@ module Prisma
|
|
47
48
|
|
48
49
|
# Configures a group. The instance of the current {http://api.rubyonrails.org/classes/ActionController/Base.html ActionController} is being passed as an argument into the block.
|
49
50
|
# As an example, tracking daily active users could be as simple as:
|
50
|
-
# Prisma.setup |config|
|
51
|
+
# Prisma.setup do |config|
|
51
52
|
# config.group :logged_in { |controller| controller.current_user.id }
|
52
53
|
# end
|
53
54
|
#
|
54
55
|
# @param [Symbol/String] name for identifying the group, it is used as part of the redis key.
|
55
|
-
# @param [
|
56
|
+
# @param [Hash] options where +:type+ is either +:counter+ (default) or +:bitmap+, and where +:description+ is an optional description (used in the admin UI)
|
56
57
|
# @param [Block] block returning a String (or a meaningful +.to_s output+) which is used for identifying a counter inside a group, Prisma doesn't count a request if block returns +nil+ or +false+
|
57
|
-
def self.group(name,
|
58
|
-
@@groups[name] = Group.new(:
|
58
|
+
def self.group(name, options={}, &block)
|
59
|
+
@@groups[name] = Group.new(options.merge(name: name, block: block))
|
59
60
|
end
|
60
61
|
|
61
62
|
# Returns a default or configured +Redis+ instance wrapped in a +Redis::Namespace+
|
@@ -65,14 +66,14 @@ module Prisma
|
|
65
66
|
case @@redis
|
66
67
|
when String
|
67
68
|
if @@redis =~ /redis\:\/\//
|
68
|
-
redis = Redis.connect(:
|
69
|
+
redis = Redis.connect(url: @@redis, thread_safe: true)
|
69
70
|
else
|
70
71
|
host, port, db = @@redis.split(':')
|
71
|
-
redis = Redis.new(:
|
72
|
+
redis = Redis.new(host: host, port: port, thread_safe: true, db: db)
|
72
73
|
end
|
73
|
-
Redis::Namespace.new(redis_namespace, :
|
74
|
+
Redis::Namespace.new(redis_namespace, redis: redis)
|
74
75
|
else
|
75
|
-
Redis::Namespace.new(redis_namespace, :
|
76
|
+
Redis::Namespace.new(redis_namespace, redis: @@redis)
|
76
77
|
end
|
77
78
|
end.call
|
78
79
|
end
|
@@ -101,7 +102,9 @@ module Prisma
|
|
101
102
|
def self.store_configuration
|
102
103
|
redis.del 'configuration'
|
103
104
|
groups.values.each do |group|
|
104
|
-
redis.
|
105
|
+
redis.rpush 'configuration', group.name
|
106
|
+
redis.set "configuration:description:#{group.name}", group.description if group.description
|
107
|
+
redis.set "configuration:type:#{group.name}", group.type
|
105
108
|
end
|
106
109
|
end
|
107
110
|
end
|
data/lib/prisma/filter.rb
CHANGED
@@ -13,8 +13,16 @@ module Prisma
|
|
13
13
|
Prisma.groups.each do |name, group|
|
14
14
|
redis_key = Prisma.redis_key(name)
|
15
15
|
value = group.block.call(self)
|
16
|
-
Prisma.redis.hincrby redis_key, value, 1 if value
|
17
16
|
|
17
|
+
case group.type
|
18
|
+
when :bitmap
|
19
|
+
next if value.to_i == 0
|
20
|
+
setbit_key = Redis::Namespace::COMMANDS.include?('setbit') ? redis_key : "#{Prisma.redis_namespace}:#{redis_key}"
|
21
|
+
Prisma.redis.setbit setbit_key, value.to_i, 1
|
22
|
+
when :counter
|
23
|
+
next unless value
|
24
|
+
Prisma.redis.incr redis_key
|
25
|
+
end
|
18
26
|
Prisma.redis.expire redis_key, Prisma.redis_expire if Prisma.redis_expiration_duration
|
19
27
|
end
|
20
28
|
end
|
data/lib/prisma/group.rb
CHANGED
@@ -4,15 +4,24 @@ module Prisma
|
|
4
4
|
# The name of the group, typically a +Symbol+
|
5
5
|
attr_accessor :name
|
6
6
|
|
7
|
+
# The type of the group, +:counter+ or +:bitmap+
|
8
|
+
attr_accessor :type
|
9
|
+
|
7
10
|
# The description of the group, typcially a +String+
|
8
11
|
attr_accessor :description
|
9
12
|
|
10
|
-
#
|
13
|
+
# Block which gets called to evaluate if request should be counted and depending on the type how the request should be counted.
|
14
|
+
# When +type+ is +:counter+ the request is getting counted as long as the return value is not nil or false.
|
15
|
+
# When +type+ is +:bitmap+ the request is getting counted as long as the return value is an integer.
|
11
16
|
attr_accessor :block
|
12
17
|
|
13
18
|
# Initialize +Group+ from a hash
|
14
19
|
def initialize(options={})
|
20
|
+
options.reverse_merge!(type: :counter)
|
21
|
+
raise ArgumentError.new("Type #{options[:type].inspect} not allowed") unless [:counter, :bitmap].include? options[:type]
|
22
|
+
|
15
23
|
self.name = options[:name]
|
24
|
+
self.type = options[:type]
|
16
25
|
self.description = options[:description]
|
17
26
|
self.block = options[:block]
|
18
27
|
end
|
@@ -26,7 +35,15 @@ module Prisma
|
|
26
35
|
range = range..range if range.is_a? Date
|
27
36
|
data = {}
|
28
37
|
range.each do |date|
|
29
|
-
|
38
|
+
case type
|
39
|
+
when :counter
|
40
|
+
data[date] = Prisma.redis.get(Prisma.redis_key(name, date)).to_i
|
41
|
+
when :bitmap
|
42
|
+
bitstring = Prisma.redis.get(Prisma.redis_key(name, date)) || ''
|
43
|
+
string = bitstring.unpack('b*').first
|
44
|
+
bitmap = Bitset.from_s(string)
|
45
|
+
data[date] = bitmap.cardinality
|
46
|
+
end
|
30
47
|
end
|
31
48
|
data
|
32
49
|
end
|
data/lib/prisma/server.rb
CHANGED
@@ -45,8 +45,10 @@ module Prisma
|
|
45
45
|
private
|
46
46
|
|
47
47
|
def groups
|
48
|
-
Prisma.redis.
|
49
|
-
Prisma
|
48
|
+
Prisma.redis.lrange('configuration', 0, -1).map do |name|
|
49
|
+
type = Prisma.redis.get("configuration:type:#{name}").to_sym
|
50
|
+
description = Prisma.redis.get("configuration:description:#{name}")
|
51
|
+
Prisma::Group.new(name: name, type: type, description: description)
|
50
52
|
end
|
51
53
|
end
|
52
54
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prisma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -43,6 +43,22 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: 1.0.2
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: redis
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.2.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.2.0
|
46
62
|
- !ruby/object:Gem::Dependency
|
47
63
|
name: sinatra
|
48
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,6 +91,22 @@ dependencies:
|
|
75
91
|
- - ~>
|
76
92
|
- !ruby/object:Gem::Version
|
77
93
|
version: 0.1.2
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: bitset
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 0.1.0
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.1.0
|
78
110
|
- !ruby/object:Gem::Dependency
|
79
111
|
name: rspec-rails
|
80
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -320,7 +352,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
320
352
|
version: '0'
|
321
353
|
segments:
|
322
354
|
- 0
|
323
|
-
hash:
|
355
|
+
hash: 2186605231112697474
|
324
356
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
325
357
|
none: false
|
326
358
|
requirements:
|