prisma 0.1.2 → 0.2.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.
- 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:
|