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 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(:db => 1)
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 [String] description for describing the gorup, it is used in the admin interface.
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, description=nil, &block)
58
- @@groups[name] = Group.new(:name => name, :description => description, :block => block)
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(:url => @@redis, :thread_safe => true)
69
+ redis = Redis.connect(url: @@redis, thread_safe: true)
69
70
  else
70
71
  host, port, db = @@redis.split(':')
71
- redis = Redis.new(:host => host, :port => port, :thread_safe => true, :db => db)
72
+ redis = Redis.new(host: host, port: port, thread_safe: true, db: db)
72
73
  end
73
- Redis::Namespace.new(redis_namespace, :redis => redis)
74
+ Redis::Namespace.new(redis_namespace, redis: redis)
74
75
  else
75
- Redis::Namespace.new(redis_namespace, :redis => @@redis)
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.hset 'configuration', group.name, group.description
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
- # The block which evaluates to a +String+ or meaningful +Object.to_s+
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
- data[date] = Prisma.redis.hlen Prisma.redis_key(name, date)
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.hgetall('configuration').map do |name, description|
49
- Prisma::Group.new(:name => name, :description => description)
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.1.2
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-05 00:00:00.000000000 Z
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: 4578263424559141618
355
+ hash: 2186605231112697474
324
356
  required_rubygems_version: !ruby/object:Gem::Requirement
325
357
  none: false
326
358
  requirements: