familia 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +19 -0
- data/README.rdoc +16 -1
- data/Rakefile +1 -3
- data/VERSION.yml +1 -1
- data/familia.gemspec +5 -2
- data/lib/familia.rb +14 -6
- data/lib/familia/core_ext.rb +21 -0
- data/lib/familia/object.rb +54 -19
- data/lib/familia/redisobject.rb +69 -9
- data/lib/familia/test_helpers.rb +6 -0
- data/try/10_familia_try.rb +17 -0
- data/try/20_redis_object_try.rb +29 -2
- metadata +13 -2
data/CHANGES.txt
CHANGED
@@ -1,5 +1,24 @@
|
|
1
1
|
FAMILIA, CHANGES
|
2
2
|
|
3
|
+
|
4
|
+
#### 0.7.1 (2011-04-09) ###############################
|
5
|
+
|
6
|
+
* FIXED: Explicitly convert boolean conf options to true or false. Redis client
|
7
|
+
treats "true" as false.
|
8
|
+
* FIXED: Clone options for each RedisObject instance to prevent cross contamination.
|
9
|
+
* CHANGE: Fix for Familia objects with custom suffixes
|
10
|
+
* CHANGE: Familia::String methods that modify the key now automatically update_expiration.
|
11
|
+
* CHANGE: Familia::Object.prefix replaces :: in class names with Familia.delim
|
12
|
+
* CHANGE: Use Familia::Object#object_proxy instead of Familia::Object.string :object
|
13
|
+
* ADDED: Familia.qnow, Familia::Object.qstamp, RedisObject#qstamp
|
14
|
+
* ADDED: RedisObject option: quantize
|
15
|
+
* ADDED: Familia::Object#savenx
|
16
|
+
* ADDED: Can now include a Familia object in Familia::Object.index (it uses its index)
|
17
|
+
* ADDED: Dependency multi_json
|
18
|
+
* ADDED: Hash#to_json, Hash.from_json, Array#to_json, Array.from_json
|
19
|
+
* ADDED: Familia::Object#update!
|
20
|
+
|
21
|
+
|
3
22
|
#### 0.7.0 (2011-03-04) ###############################
|
4
23
|
|
5
24
|
* CHANGE: Use RedisObject#multi_from_redis when possible (uses mget command)
|
data/README.rdoc
CHANGED
@@ -1,8 +1,23 @@
|
|
1
|
-
# Familia - 0.
|
1
|
+
# Familia - 0.7 BETA
|
2
2
|
|
3
3
|
**Organize and store ruby objects in Redis**
|
4
4
|
|
5
5
|
|
6
|
+
## Basic Example
|
7
|
+
|
8
|
+
class Bone < Storable
|
9
|
+
include Familia
|
10
|
+
index [:token, :name]
|
11
|
+
field :token
|
12
|
+
field :name
|
13
|
+
list :owners
|
14
|
+
set :tags
|
15
|
+
zset :metrics
|
16
|
+
hash :props
|
17
|
+
string :value, :default => "GREAT!"
|
18
|
+
end
|
19
|
+
|
20
|
+
|
6
21
|
## More Information
|
7
22
|
|
8
23
|
* [Codes](http://github.com/delano/familia)
|
data/Rakefile
CHANGED
@@ -29,9 +29,7 @@ begin
|
|
29
29
|
gem.add_dependency("uri-redis", ">= 0.4.2")
|
30
30
|
gem.add_dependency("gibbler", ">= 0.8.6")
|
31
31
|
gem.add_dependency("storable", ">= 0.8.6")
|
32
|
-
|
33
|
-
#gem.add_development_dependency("rspec", ">= 1.2.9")
|
34
|
-
#gem.add_development_dependency("mocha", ">= 0.9.8")
|
32
|
+
gem.add_dependency("multi_json", ">= 0.0.5")
|
35
33
|
end
|
36
34
|
Jeweler::GemcutterTasks.new
|
37
35
|
rescue LoadError
|
data/VERSION.yml
CHANGED
data/familia.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{familia}
|
8
|
-
s.version = "0.7.
|
8
|
+
s.version = "0.7.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Delano Mandelbaum"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-04-11}
|
13
13
|
s.description = %q{Organize and store ruby objects in Redis}
|
14
14
|
s.email = %q{delano@solutious.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -55,17 +55,20 @@ Gem::Specification.new do |s|
|
|
55
55
|
s.add_runtime_dependency(%q<uri-redis>, [">= 0.4.2"])
|
56
56
|
s.add_runtime_dependency(%q<gibbler>, [">= 0.8.6"])
|
57
57
|
s.add_runtime_dependency(%q<storable>, [">= 0.8.6"])
|
58
|
+
s.add_runtime_dependency(%q<multi_json>, [">= 0.0.5"])
|
58
59
|
else
|
59
60
|
s.add_dependency(%q<redis>, [">= 2.1.0"])
|
60
61
|
s.add_dependency(%q<uri-redis>, [">= 0.4.2"])
|
61
62
|
s.add_dependency(%q<gibbler>, [">= 0.8.6"])
|
62
63
|
s.add_dependency(%q<storable>, [">= 0.8.6"])
|
64
|
+
s.add_dependency(%q<multi_json>, [">= 0.0.5"])
|
63
65
|
end
|
64
66
|
else
|
65
67
|
s.add_dependency(%q<redis>, [">= 2.1.0"])
|
66
68
|
s.add_dependency(%q<uri-redis>, [">= 0.4.2"])
|
67
69
|
s.add_dependency(%q<gibbler>, [">= 0.8.6"])
|
68
70
|
s.add_dependency(%q<storable>, [">= 0.8.6"])
|
71
|
+
s.add_dependency(%q<multi_json>, [">= 0.0.5"])
|
69
72
|
end
|
70
73
|
end
|
71
74
|
|
data/lib/familia.rb
CHANGED
@@ -3,6 +3,7 @@ FAMILIA_LIB_HOME = File.expand_path File.dirname(__FILE__) unless defined?(FAMIL
|
|
3
3
|
require 'uri/redis'
|
4
4
|
require 'gibbler'
|
5
5
|
require 'familia/core_ext'
|
6
|
+
require 'multi_json'
|
6
7
|
|
7
8
|
module Familia
|
8
9
|
module VERSION
|
@@ -85,7 +86,9 @@ module Familia
|
|
85
86
|
uri &&= URI.parse uri if String === uri
|
86
87
|
uri ||= Familia.uri
|
87
88
|
conf = uri.conf
|
88
|
-
conf[:thread_safe] = true unless conf.has_key?(:thread_safe)
|
89
|
+
conf[:thread_safe] = "true" unless conf.has_key?(:thread_safe)
|
90
|
+
conf[:thread_safe] = conf[:thread_safe].to_s == "true"
|
91
|
+
conf[:logging] = conf[:logging].to_s == "true"
|
89
92
|
if conf.has_key?(:logging) && conf[:logging].to_s == "true"
|
90
93
|
require 'logger'
|
91
94
|
require 'log4r'
|
@@ -128,6 +131,16 @@ module Familia
|
|
128
131
|
end
|
129
132
|
@apiversion
|
130
133
|
end
|
134
|
+
def now n=Time.now
|
135
|
+
n.utc.to_i
|
136
|
+
end
|
137
|
+
# A quantized timestamp
|
138
|
+
# e.g. 12:32 -> 12:30
|
139
|
+
#
|
140
|
+
def qnow quantum=10.minutes, now=Familia.now
|
141
|
+
rounded = now - (now % quantum)
|
142
|
+
Time.at(rounded).utc.to_i
|
143
|
+
end
|
131
144
|
end
|
132
145
|
|
133
146
|
class Problem < RuntimeError; end
|
@@ -148,11 +161,6 @@ module Familia
|
|
148
161
|
obj.send :include, Gibbler::Complex
|
149
162
|
obj.extend Familia::ClassMethods
|
150
163
|
obj.class_zset :instances, :class => obj, :reference => true
|
151
|
-
# :object is a special redis object because its reserved
|
152
|
-
# for storing the marshaled instance data (e.g. to_json).
|
153
|
-
# When it isn't defined explicitly we define it here b/c
|
154
|
-
# it's assumed to exist in other places (see #save).
|
155
|
-
obj.string :object, :class => obj unless obj.redis_object? :object
|
156
164
|
Familia.classes << obj
|
157
165
|
end
|
158
166
|
|
data/lib/familia/core_ext.rb
CHANGED
@@ -7,6 +7,27 @@ class Symbol
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
+
class Hash
|
11
|
+
unless method_defined?(:to_json)
|
12
|
+
def to_json
|
13
|
+
MultiJson.encode self
|
14
|
+
end
|
15
|
+
def self.from_json str
|
16
|
+
MultiJson.decode str
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
class Array
|
21
|
+
unless method_defined?(:to_json)
|
22
|
+
def to_json
|
23
|
+
MultiJson.encode self
|
24
|
+
end
|
25
|
+
def self.from_json str
|
26
|
+
MultiJson.decode str
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
10
31
|
# Assumes Time::Units and Numeric mixins are available.
|
11
32
|
class String
|
12
33
|
def in_seconds
|
data/lib/familia/object.rb
CHANGED
@@ -52,18 +52,12 @@ module Familia
|
|
52
52
|
names
|
53
53
|
end
|
54
54
|
end
|
55
|
-
|
56
55
|
def inherited(obj)
|
57
56
|
obj.db = self.db
|
58
57
|
obj.uri = self.uri
|
59
58
|
obj.ttl = self.ttl
|
60
59
|
obj.parent = self
|
61
60
|
obj.class_zset :instances, :class => obj, :reference => true
|
62
|
-
# :object is a special redis object because its reserved
|
63
|
-
# for storing the marshaled instance data (e.g. to_json).
|
64
|
-
# When it isn't defined explicitly we define it here b/c
|
65
|
-
# it's assumed to exist in other places (see #save).
|
66
|
-
obj.string :object, :class => obj unless obj.redis_object? :object
|
67
61
|
Familia.classes << obj
|
68
62
|
super(obj)
|
69
63
|
end
|
@@ -97,13 +91,20 @@ module Familia
|
|
97
91
|
redis_objects[name]
|
98
92
|
end
|
99
93
|
|
94
|
+
def qstamp quantum=nil, pattern=nil, now=Familia.now
|
95
|
+
quantum ||= ttl || 10.minutes
|
96
|
+
pattern ||= '%H%M'
|
97
|
+
rounded = now - (now % quantum)
|
98
|
+
Time.at(rounded).utc.strftime(pattern)
|
99
|
+
end
|
100
|
+
|
100
101
|
# Creates a class method called +name+ that
|
101
102
|
# returns an instance of the RedisObject +klass+
|
102
103
|
def install_class_redis_object name, klass, opts
|
103
104
|
raise ArgumentError, "Name is blank" if name.to_s.empty?
|
104
105
|
name = name.to_s.to_sym
|
105
|
-
opts
|
106
|
-
opts[:parent]
|
106
|
+
opts = opts.nil? ? {} : opts.clone
|
107
|
+
opts[:parent] = self unless opts.has_key?(:parent)
|
107
108
|
# TODO: investigate using metaclass.redis_objects
|
108
109
|
class_redis_objects_order << name
|
109
110
|
class_redis_objects[name] = OpenStruct.new
|
@@ -179,7 +180,7 @@ module Familia
|
|
179
180
|
val
|
180
181
|
end
|
181
182
|
def prefix=(a) @prefix = a end
|
182
|
-
def prefix(a=nil) @prefix = a if a; @prefix || self.name.downcase.to_sym end
|
183
|
+
def prefix(a=nil) @prefix = a if a; @prefix || self.name.downcase.gsub('::', Familia.delim).to_sym end
|
183
184
|
# TODO: grab db, ttl, uri from parent
|
184
185
|
#def parent=(a) @parent = a end
|
185
186
|
#def parent(a=nil) @parent = a if a; @parent end
|
@@ -327,14 +328,22 @@ module Familia
|
|
327
328
|
# See RedisObject.install_redis_object
|
328
329
|
self.class.redis_objects.each_pair do |name, redis_object_definition|
|
329
330
|
klass, opts = redis_object_definition.klass, redis_object_definition.opts
|
330
|
-
opts
|
331
|
-
opts[:parent]
|
331
|
+
opts = opts.nil? ? {} : opts.clone
|
332
|
+
opts[:parent] = self unless opts.has_key?(:parent)
|
332
333
|
redis_object = klass.new name, opts
|
333
334
|
redis_object.freeze
|
334
335
|
self.instance_variable_set "@#{name}", redis_object
|
335
336
|
end
|
336
337
|
end
|
337
338
|
|
339
|
+
def qstamp quantum=nil, pattern=nil, now=Familia.now
|
340
|
+
self.class.qstamp ttl, pattern, now
|
341
|
+
end
|
342
|
+
|
343
|
+
def from_redis
|
344
|
+
self.class.from_redis self.index
|
345
|
+
end
|
346
|
+
|
338
347
|
def redis
|
339
348
|
self.class.redis
|
340
349
|
end
|
@@ -380,21 +389,43 @@ module Familia
|
|
380
389
|
end
|
381
390
|
self.class.rediskey self.index, suffix
|
382
391
|
end
|
383
|
-
def
|
392
|
+
def object_proxy
|
393
|
+
@object_proxy ||= Familia::String.new self.rediskey, :ttl => ttl, :class => self.class
|
394
|
+
@object_proxy
|
395
|
+
end
|
396
|
+
def save meth=:set
|
384
397
|
#Familia.trace :SAVE, Familia.redis(self.class.uri), redisuri, caller.first if Familia.debug?
|
385
398
|
preprocess if respond_to?(:preprocess)
|
386
399
|
self.update_time if self.respond_to?(:update_time)
|
387
|
-
#
|
388
|
-
ret = self.object.set self # object is a name reserved by Familia
|
400
|
+
ret = object_proxy.send(meth, self) # object is a name reserved by Familia
|
389
401
|
unless ret.nil?
|
390
402
|
now = Time.now.utc.to_i
|
391
403
|
self.class.instances.add now, self # use this set instead of Klass.keys
|
392
|
-
|
404
|
+
object_proxy.update_expiration # does nothing unless if not specified
|
393
405
|
end
|
394
|
-
true
|
406
|
+
ret == "OK" || ret == true || ret == 1
|
407
|
+
end
|
408
|
+
def savenx
|
409
|
+
save :setnx
|
410
|
+
end
|
411
|
+
def update! hsh=nil
|
412
|
+
updated = false
|
413
|
+
hsh ||= {}
|
414
|
+
if hsh.empty?
|
415
|
+
raise Familia::Problem, "No #{self.class}#{to_hash} method" unless respond_to?(:to_hash)
|
416
|
+
ret = from_redis
|
417
|
+
hsh = ret.to_hash if ret
|
418
|
+
end
|
419
|
+
hsh.keys.each { |field|
|
420
|
+
v = hsh[field.to_s] || hsh[field.to_s.to_sym]
|
421
|
+
next if v.nil?
|
422
|
+
self.send(:"#{field}=", v)
|
423
|
+
updated = true
|
424
|
+
}
|
425
|
+
updated
|
395
426
|
end
|
396
427
|
def destroy!
|
397
|
-
ret =
|
428
|
+
ret = object_proxy.delete
|
398
429
|
if Familia.debug?
|
399
430
|
Familia.trace :DELETED, Familia.redis(self.class.uri), "#{rediskey}: #{ret}", caller.first if Familia.debug?
|
400
431
|
end
|
@@ -410,7 +441,9 @@ module Familia
|
|
410
441
|
unless self.respond_to? meth
|
411
442
|
raise NoIndex, "No such method: `#{meth}' for #{self.class}"
|
412
443
|
end
|
413
|
-
self.send(meth)
|
444
|
+
ret = self.send(meth)
|
445
|
+
ret = ret.index if ret.kind_of?(Familia)
|
446
|
+
ret
|
414
447
|
}
|
415
448
|
parts.join Familia.delim
|
416
449
|
when Symbol, String
|
@@ -420,7 +453,9 @@ module Familia
|
|
420
453
|
unless self.respond_to? self.class.index
|
421
454
|
raise NoIndex, "No such method: `#{self.class.index}' for #{self.class}"
|
422
455
|
end
|
423
|
-
self.send(
|
456
|
+
ret = self.send(self.class.index)
|
457
|
+
ret = ret.index if ret.kind_of?(Familia)
|
458
|
+
ret
|
424
459
|
end
|
425
460
|
else
|
426
461
|
raise Familia::NoIndex, self
|
data/lib/familia/redisobject.rb
CHANGED
@@ -81,8 +81,20 @@ module Familia
|
|
81
81
|
# set the redis expire for this key whenever #save is called.
|
82
82
|
# You can also call it explicitly via #update_expiration.
|
83
83
|
#
|
84
|
+
# :quantize => append a quantized timestamp to the rediskey.
|
85
|
+
# Takes one of the following:
|
86
|
+
# Boolean: include the default stamp (now % 10 minutes)
|
87
|
+
# Integer: the number of seconds to quantize to (e.g. 1.hour)
|
88
|
+
# Array: All arguments for qstamp (quantum, pattern, Time.now)
|
89
|
+
#
|
84
90
|
# :default => the default value (String-only)
|
85
91
|
#
|
92
|
+
# :dump_method => the instance method to call to serialize the
|
93
|
+
# object before sending it to Redis (default: Familia.dump_method).
|
94
|
+
#
|
95
|
+
# :load_method => the class method to call to deserialize the
|
96
|
+
# object after it's read from Redis (default: Familia.load_method).
|
97
|
+
#
|
86
98
|
# :db => the redis database to use (ignored if :redis is used).
|
87
99
|
#
|
88
100
|
# :redis => an instance of Redis.
|
@@ -146,7 +158,26 @@ module Familia
|
|
146
158
|
# returns a redis key based on the parent
|
147
159
|
# object so it will include the proper index.
|
148
160
|
def rediskey
|
149
|
-
parent?
|
161
|
+
if parent?
|
162
|
+
# We need to check if the parent has a specific suffix
|
163
|
+
# for the case where we have specified one other than :object.
|
164
|
+
suffix = parent.kind_of?(Familia) && parent.class.suffix != :object ? parent.class.suffix : name
|
165
|
+
k = parent.rediskey(name, nil)
|
166
|
+
else
|
167
|
+
k = [name].flatten.compact.join(Familia.delim)
|
168
|
+
end
|
169
|
+
if @opts[:quantize]
|
170
|
+
args = case @opts[:quantize]
|
171
|
+
when Numeric
|
172
|
+
[@opts[:quantize]] # :quantize => 1.minute
|
173
|
+
when Array
|
174
|
+
@opts[:quantize] # :quantize => [1.day, '%m%D']
|
175
|
+
else
|
176
|
+
[] # :quantize => true
|
177
|
+
end
|
178
|
+
k = [k, qstamp(*args)].join(Familia.delim)
|
179
|
+
end
|
180
|
+
k
|
150
181
|
end
|
151
182
|
|
152
183
|
def class?
|
@@ -157,6 +188,13 @@ module Familia
|
|
157
188
|
Class === parent || Module === parent || parent.kind_of?(Familia)
|
158
189
|
end
|
159
190
|
|
191
|
+
def qstamp quantum=nil, pattern=nil, now=Familia.now
|
192
|
+
quantum ||= ttl || 10.minutes
|
193
|
+
pattern ||= '%H%M'
|
194
|
+
rounded = now - (now % quantum)
|
195
|
+
Time.at(rounded).utc.strftime(pattern)
|
196
|
+
end
|
197
|
+
|
160
198
|
def update_expiration(ttl=nil)
|
161
199
|
ttl ||= self.ttl
|
162
200
|
return if ttl.to_i.zero? # nil will be zero
|
@@ -891,28 +929,44 @@ module Familia
|
|
891
929
|
alias_method :replace, :value=
|
892
930
|
alias_method :set, :value=
|
893
931
|
|
932
|
+
def setnx v
|
933
|
+
ret = redis.setnx rediskey, to_redis(v)
|
934
|
+
update_expiration
|
935
|
+
ret
|
936
|
+
end
|
937
|
+
|
894
938
|
def increment
|
895
|
-
redis.incr rediskey
|
939
|
+
ret = redis.incr rediskey
|
940
|
+
update_expiration
|
941
|
+
ret
|
896
942
|
end
|
897
943
|
alias_method :incr, :increment
|
898
944
|
|
899
945
|
def incrementby int
|
900
|
-
redis.incrby rediskey, int.to_i
|
946
|
+
ret = redis.incrby rediskey, int.to_i
|
947
|
+
update_expiration
|
948
|
+
ret
|
901
949
|
end
|
902
950
|
alias_method :incrby, :incrementby
|
903
951
|
|
904
952
|
def decrement
|
905
|
-
redis.decr rediskey
|
953
|
+
ret = redis.decr rediskey
|
954
|
+
update_expiration
|
955
|
+
ret
|
906
956
|
end
|
907
957
|
alias_method :decr, :decrement
|
908
958
|
|
909
959
|
def decrementby int
|
910
|
-
redis.decrby rediskey, int.to_i
|
960
|
+
ret = redis.decrby rediskey, int.to_i
|
961
|
+
update_expiration
|
962
|
+
ret
|
911
963
|
end
|
912
964
|
alias_method :decrby, :decrementby
|
913
965
|
|
914
966
|
def append v
|
915
|
-
redis.append rediskey, v
|
967
|
+
ret = redis.append rediskey, v
|
968
|
+
update_expiration
|
969
|
+
ret
|
916
970
|
end
|
917
971
|
alias_method :<<, :append
|
918
972
|
|
@@ -921,7 +975,9 @@ module Familia
|
|
921
975
|
end
|
922
976
|
|
923
977
|
def setbit offset, v
|
924
|
-
redis.setbit rediskey, offset, v
|
978
|
+
ret = redis.setbit rediskey, offset, v
|
979
|
+
update_expiration
|
980
|
+
ret
|
925
981
|
end
|
926
982
|
|
927
983
|
def getrange spoint, epoint
|
@@ -929,11 +985,15 @@ module Familia
|
|
929
985
|
end
|
930
986
|
|
931
987
|
def setrange offset, v
|
932
|
-
redis.setrange rediskey, offset, v
|
988
|
+
ret = redis.setrange rediskey, offset, v
|
989
|
+
update_expiration
|
990
|
+
ret
|
933
991
|
end
|
934
992
|
|
935
993
|
def getset v
|
936
|
-
redis.getset rediskey, v
|
994
|
+
ret = redis.getset rediskey, v
|
995
|
+
update_expiration
|
996
|
+
ret
|
937
997
|
end
|
938
998
|
|
939
999
|
def nil?
|
data/lib/familia/test_helpers.rb
CHANGED
data/try/10_familia_try.rb
CHANGED
@@ -34,3 +34,20 @@ Bone.list? :owners
|
|
34
34
|
definition = Bone.list :owners
|
35
35
|
definition.klass
|
36
36
|
#=> Familia::List
|
37
|
+
|
38
|
+
## Familia.now
|
39
|
+
Familia.now Time.parse('2011-04-10 20:56:20 UTC').utc
|
40
|
+
#=> 1302468980
|
41
|
+
|
42
|
+
## Familia.qnow
|
43
|
+
Familia.qnow 10.minutes, 1302468980
|
44
|
+
#=> 1302468600
|
45
|
+
|
46
|
+
## Familia::Object.qstamp
|
47
|
+
Limiter.qstamp 10.minutes, '%H:%M', 1302468980
|
48
|
+
#=> '20:50'
|
49
|
+
|
50
|
+
## Familia::Object#qstamp
|
51
|
+
limiter = Limiter.new :request
|
52
|
+
limiter.qstamp 10.minutes, '%H:%M', 1302468980
|
53
|
+
##=> '20:50'
|
data/try/20_redis_object_try.rb
CHANGED
@@ -5,8 +5,8 @@ Familia.apiversion = 'v1'
|
|
5
5
|
|
6
6
|
|
7
7
|
## Redis Objects are unique per instance of a Familia class
|
8
|
-
@a = Bone.new 'atoken'
|
9
|
-
@b = Bone.new '
|
8
|
+
@a = Bone.new 'atoken', :name1
|
9
|
+
@b = Bone.new 'atoken', :name2
|
10
10
|
@a.owners.rediskey == @b.owners.rediskey
|
11
11
|
#=> false
|
12
12
|
|
@@ -15,4 +15,31 @@ Familia.apiversion = 'v1'
|
|
15
15
|
#=> true
|
16
16
|
|
17
17
|
|
18
|
+
## Limiter#qstamp
|
19
|
+
@limiter = Limiter.new :requests
|
20
|
+
@limiter.counter.qstamp 10.minutes, '%H:%M', 1302468980
|
21
|
+
#=> '20:50'
|
18
22
|
|
23
|
+
## Redis Objects can be stored to quantized keys
|
24
|
+
@limiter.counter.rediskey
|
25
|
+
#=> "v1:limiter:requests:counter:20:50"
|
26
|
+
|
27
|
+
## Increment counter
|
28
|
+
@limiter.counter.clear
|
29
|
+
@limiter.counter.increment
|
30
|
+
#=> 1
|
31
|
+
|
32
|
+
## Check ttl
|
33
|
+
@limiter.counter.ttl
|
34
|
+
#=> 3600
|
35
|
+
|
36
|
+
## Check ttl for a different instance
|
37
|
+
## (this exists to make sure options are cloned for each instance)
|
38
|
+
@limiter2 = Limiter.new :requests
|
39
|
+
@limiter2.counter.ttl
|
40
|
+
#=> 3600
|
41
|
+
|
42
|
+
## Check realttl
|
43
|
+
sleep 1
|
44
|
+
@limiter.counter.realttl
|
45
|
+
#=> 3600-1
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: familia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.7.
|
5
|
+
version: 0.7.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Delano Mandelbaum
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-04-11 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -57,6 +57,17 @@ dependencies:
|
|
57
57
|
version: 0.8.6
|
58
58
|
type: :runtime
|
59
59
|
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: multi_json
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.0.5
|
69
|
+
type: :runtime
|
70
|
+
version_requirements: *id005
|
60
71
|
description: Organize and store ruby objects in Redis
|
61
72
|
email: delano@solutious.com
|
62
73
|
executables: []
|