redis-objects 1.0.1 → 1.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.rdoc +18 -0
- data/README.md +12 -4
- data/Rakefile +5 -1
- data/lib/redis/base_object.rb +1 -1
- data/lib/redis/objects.rb +28 -4
- data/lib/redis/objects/connection_pool_proxy.rb +30 -0
- data/lib/redis/objects/counters.rb +1 -1
- data/lib/redis/objects/hashes.rb +1 -1
- data/lib/redis/objects/lists.rb +1 -1
- data/lib/redis/objects/sets.rb +1 -1
- data/lib/redis/objects/sorted_sets.rb +1 -1
- data/lib/redis/objects/values.rb +1 -1
- data/lib/redis/objects/version.rb +1 -1
- data/spec/redis_objects_conn_spec.rb +114 -5
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc70bd55cafac46d93b6dc5dcd24d2e116c00d1e
|
4
|
+
data.tar.gz: d98febd210c47c61f8511f023e09edf86d848f25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d854a41164664e2e4dafdf3c25e05ad6281ba305cb4c28fcccbff6777b4f2bcc9f773b96e0c7423552957395ab21aa7c0bef5175d70fe4aae7677c04c457c7d4
|
7
|
+
data.tar.gz: 090c58f4cbe376b4a37b0bd9c1b70894f036c8bc5b94a62c58e1047c0a175f8418659b260ca26daa3a3c21f6e2c9642694f1176f8c8bc390a6914eccd05e90bb
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
= Changelog for Redis::Objects
|
2
2
|
|
3
|
+
== 1.1.0 (21 Jan 2015)
|
4
|
+
|
5
|
+
* Support connection_pool useage via a proxy object [Jared Jenkins]
|
6
|
+
|
7
|
+
* Fix typo on :counter usage [Kevin Bongart]
|
8
|
+
|
9
|
+
* Use parent redis_id_field if present [Arnaud Lavrard]
|
10
|
+
|
11
|
+
* Fetch the objects options through a redis_options method [Arnaud Lavrard]
|
12
|
+
|
13
|
+
== 1.0.1 (14 Oct 2014)
|
14
|
+
|
15
|
+
* Array handling for unmarshal [dreyks]
|
16
|
+
|
17
|
+
* Test against Ruby 2.1 / 2.2 on Travis CI [tricknotes]
|
18
|
+
|
19
|
+
* Redis::Set#randmember method accept count as optional parameter [xeviknal]
|
20
|
+
|
3
21
|
== 1.0.0 (25 Jul 2014)
|
4
22
|
|
5
23
|
* Fix expiration filter to handle atomic blocks, remove method aliasing [nateware]
|
data/README.md
CHANGED
@@ -36,10 +36,17 @@ Add it to your Gemfile as:
|
|
36
36
|
gem 'redis-objects'
|
37
37
|
~~~
|
38
38
|
|
39
|
-
Redis::Objects needs a handle created by `Redis.new
|
40
|
-
is to set `Redis.current` to point to your server, which Redis::Objects will
|
41
|
-
pick up automatically.
|
39
|
+
Redis::Objects needs a handle created by `Redis.new` or a [ConnectionPool](https://github.com/mperham/connection_pool):
|
42
40
|
|
41
|
+
The recommended approach is to use a `ConnectionPool` since this guarantees that most timeouts in the `redis` client
|
42
|
+
do not pollute your existing connection. However, you need to make sure that both `:timeout` and `:size` are set appropriately
|
43
|
+
in a multithreaded environment.
|
44
|
+
~~~ruby
|
45
|
+
require 'connection_pool'
|
46
|
+
Redis::Objects.redis = ConnectionPool.new(size: 5, timeout: 5) { Redis.new(:host => '127.0.0.1', :port => 6379) }
|
47
|
+
~~~
|
48
|
+
|
49
|
+
Redis::Objects can also default to `Redis.current` if `Redis::Objects.redis` is not set.
|
43
50
|
~~~ruby
|
44
51
|
Redis.current = Redis.new(:host => '127.0.0.1', :port => 6379)
|
45
52
|
~~~
|
@@ -64,6 +71,7 @@ class Post
|
|
64
71
|
include Redis::Objects
|
65
72
|
end
|
66
73
|
|
74
|
+
# you can also use a ConnectionPool here as well
|
67
75
|
User.redis = Redis.new(:host => '1.2.3.4')
|
68
76
|
Post.redis = Redis.new(:host => '5.6.7.8')
|
69
77
|
~~~
|
@@ -97,7 +105,7 @@ user.id # 1
|
|
97
105
|
user.my_posts.increment
|
98
106
|
user.my_posts.increment
|
99
107
|
user.my_posts.increment
|
100
|
-
puts user.my_posts
|
108
|
+
puts user.my_posts.value # 3
|
101
109
|
user.my_posts.reset
|
102
110
|
puts user.my_posts.value # 0
|
103
111
|
user.my_posts.reset 5
|
data/Rakefile
CHANGED
@@ -4,6 +4,10 @@ desc "run all the specs"
|
|
4
4
|
task :test do
|
5
5
|
sh "bacon spec/*_spec.rb"
|
6
6
|
end
|
7
|
-
|
8
7
|
task :default => :test
|
9
8
|
|
9
|
+
desc "show changelog"
|
10
|
+
task :changelog do
|
11
|
+
latest = `git tag |tail -1`.chomp
|
12
|
+
system "git log --pretty=format:'* %s %b [%an]' #{latest}..HEAD"
|
13
|
+
end
|
data/lib/redis/base_object.rb
CHANGED
@@ -4,7 +4,7 @@ class Redis
|
|
4
4
|
def initialize(key, *args)
|
5
5
|
@key = key.is_a?(Array) ? key.flatten.join(':') : key
|
6
6
|
@options = args.last.is_a?(Hash) ? args.pop : {}
|
7
|
-
@myredis = args.first
|
7
|
+
@myredis = Objects::ConnectionPoolProxy.proxy_if_needed(args.first)
|
8
8
|
end
|
9
9
|
|
10
10
|
# Dynamically query the handle to enable resetting midstream
|
data/lib/redis/objects.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Redis::Objects - Lightweight object layer around redis-rb
|
2
2
|
# See README.rdoc for usage and approach.
|
3
3
|
require 'redis'
|
4
|
+
require 'redis/objects/connection_pool_proxy'
|
4
5
|
|
5
6
|
class Redis
|
6
7
|
autoload :Counter, 'redis/counter'
|
@@ -60,7 +61,7 @@ class Redis
|
|
60
61
|
|
61
62
|
class << self
|
62
63
|
def redis=(conn)
|
63
|
-
@redis = conn
|
64
|
+
@redis = Objects::ConnectionPoolProxy.proxy_if_needed(conn)
|
64
65
|
end
|
65
66
|
def redis
|
66
67
|
@redis || $redis || Redis.current ||
|
@@ -88,7 +89,10 @@ class Redis
|
|
88
89
|
# Class methods that appear in your class when you include Redis::Objects.
|
89
90
|
module ClassMethods
|
90
91
|
# Enable per-class connections (eg, User and Post can use diff redis-server)
|
91
|
-
|
92
|
+
def redis=(conn)
|
93
|
+
@redis = Objects::ConnectionPoolProxy.proxy_if_needed(conn)
|
94
|
+
end
|
95
|
+
|
92
96
|
def redis
|
93
97
|
@redis || Objects.redis
|
94
98
|
end
|
@@ -109,9 +113,19 @@ class Redis
|
|
109
113
|
downcase
|
110
114
|
end
|
111
115
|
|
116
|
+
def redis_options(name)
|
117
|
+
klass = first_ancestor_with(name)
|
118
|
+
return klass.redis_objects[name.to_sym] || {}
|
119
|
+
end
|
120
|
+
|
112
121
|
def redis_field_redis(name) #:nodoc:
|
113
122
|
klass = first_ancestor_with(name)
|
114
|
-
|
123
|
+
override_redis = klass.redis_objects[name.to_sym][:redis]
|
124
|
+
if override_redis
|
125
|
+
Objects::ConnectionPoolProxy.proxy_if_needed(override_redis)
|
126
|
+
else
|
127
|
+
self.redis
|
128
|
+
end
|
115
129
|
end
|
116
130
|
|
117
131
|
def redis_field_key(name, id=nil, context=self) #:nodoc:
|
@@ -143,7 +157,13 @@ class Redis
|
|
143
157
|
end
|
144
158
|
|
145
159
|
def redis_id_field(id=nil)
|
146
|
-
@redis_id_field = id || @redis_id_field
|
160
|
+
@redis_id_field = id || @redis_id_field
|
161
|
+
|
162
|
+
if superclass && superclass.respond_to?(:redis_id_field)
|
163
|
+
@redis_id_field ||= superclass.redis_id_field
|
164
|
+
end
|
165
|
+
|
166
|
+
@redis_id_field ||= :id
|
147
167
|
end
|
148
168
|
end
|
149
169
|
|
@@ -153,6 +173,10 @@ class Redis
|
|
153
173
|
def redis() self.class.redis end
|
154
174
|
def redis_objects() self.class.redis_objects end
|
155
175
|
|
176
|
+
def redis_options(name) #:nodoc:
|
177
|
+
return self.class.redis_options(name)
|
178
|
+
end
|
179
|
+
|
156
180
|
def redis_field_redis(name) #:nodoc:
|
157
181
|
return self.class.redis_field_redis(name)
|
158
182
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Redis
|
2
|
+
module Objects
|
3
|
+
class ConnectionPoolProxy
|
4
|
+
def initialize(pool)
|
5
|
+
raise ArgumentError "Should only proxy ConnectionPool!" unless self.class.should_proxy?(pool)
|
6
|
+
@pool = pool
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(name, *args, &block)
|
10
|
+
@pool.with { |x| x.send(name, *args, &block) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def respond_to_missing?(name, include_all = false)
|
14
|
+
@pool.with { |x| x.respond_to?(name, include_all) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.should_proxy?(conn)
|
18
|
+
defined?(::ConnectionPool) && conn.is_a?(::ConnectionPool)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.proxy_if_needed(conn)
|
22
|
+
if should_proxy?(conn)
|
23
|
+
ConnectionPoolProxy.new(conn)
|
24
|
+
else
|
25
|
+
conn
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -29,7 +29,7 @@ class Redis
|
|
29
29
|
instance_variable_get("@#{name}") or
|
30
30
|
instance_variable_set("@#{name}",
|
31
31
|
Redis::Counter.new(
|
32
|
-
redis_field_key(name), redis_field_redis(name),
|
32
|
+
redis_field_key(name), redis_field_redis(name), redis_options(name)
|
33
33
|
)
|
34
34
|
)
|
35
35
|
end
|
data/lib/redis/objects/hashes.rb
CHANGED
@@ -21,7 +21,7 @@ class Redis
|
|
21
21
|
instance_variable_get("@#{name}") or
|
22
22
|
instance_variable_set("@#{name}",
|
23
23
|
Redis::HashKey.new(
|
24
|
-
redis_field_key(name), redis_field_redis(name),
|
24
|
+
redis_field_key(name), redis_field_redis(name), redis_options(name)
|
25
25
|
)
|
26
26
|
)
|
27
27
|
end
|
data/lib/redis/objects/lists.rb
CHANGED
@@ -21,7 +21,7 @@ class Redis
|
|
21
21
|
instance_variable_get("@#{name}") or
|
22
22
|
instance_variable_set("@#{name}",
|
23
23
|
Redis::List.new(
|
24
|
-
redis_field_key(name), redis_field_redis(name),
|
24
|
+
redis_field_key(name), redis_field_redis(name), redis_options(name)
|
25
25
|
)
|
26
26
|
)
|
27
27
|
end
|
data/lib/redis/objects/sets.rb
CHANGED
@@ -21,7 +21,7 @@ class Redis
|
|
21
21
|
instance_variable_get("@#{name}") or
|
22
22
|
instance_variable_set("@#{name}",
|
23
23
|
Redis::Set.new(
|
24
|
-
redis_field_key(name), redis_field_redis(name),
|
24
|
+
redis_field_key(name), redis_field_redis(name), redis_options(name)
|
25
25
|
)
|
26
26
|
)
|
27
27
|
end
|
@@ -21,7 +21,7 @@ class Redis
|
|
21
21
|
instance_variable_get("@#{name}") or
|
22
22
|
instance_variable_set("@#{name}",
|
23
23
|
Redis::SortedSet.new(
|
24
|
-
redis_field_key(name), redis_field_redis(name),
|
24
|
+
redis_field_key(name), redis_field_redis(name), redis_options(name)
|
25
25
|
)
|
26
26
|
)
|
27
27
|
end
|
data/lib/redis/objects/values.rb
CHANGED
@@ -21,7 +21,7 @@ class Redis
|
|
21
21
|
instance_variable_get("@#{name}") or
|
22
22
|
instance_variable_set("@#{name}",
|
23
23
|
Redis::Value.new(
|
24
|
-
redis_field_key(name), redis_field_redis(name),
|
24
|
+
redis_field_key(name), redis_field_redis(name), redis_options(name)
|
25
25
|
)
|
26
26
|
)
|
27
27
|
end
|
@@ -4,13 +4,13 @@
|
|
4
4
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
5
5
|
|
6
6
|
require 'redis/objects'
|
7
|
+
require 'connection_pool'
|
7
8
|
|
8
9
|
BAD_REDIS = "totally bad bogus redis handle"
|
9
10
|
|
10
11
|
# Grab a global handle
|
11
12
|
describe 'Connection tests' do
|
12
|
-
it "should support overriding object handles" do
|
13
|
-
|
13
|
+
it "should support overriding object handles with a vanilla redis connection" do
|
14
14
|
class CustomConnectionObject
|
15
15
|
include Redis::Objects
|
16
16
|
|
@@ -41,7 +41,38 @@ describe 'Connection tests' do
|
|
41
41
|
obj.default_redis_value.clear
|
42
42
|
end
|
43
43
|
|
44
|
-
it "should support
|
44
|
+
it "should support overriding object handles with a connection_pool" do
|
45
|
+
class CustomConnectionObject
|
46
|
+
include Redis::Objects
|
47
|
+
|
48
|
+
def id
|
49
|
+
return 1
|
50
|
+
end
|
51
|
+
|
52
|
+
redis_handle = ConnectionPool.new { Redis.new(:host => REDIS_HOST, :port => REDIS_PORT, :db => 31) }
|
53
|
+
value :redis_value, :redis => redis_handle, :key => 'rval'
|
54
|
+
value :default_redis_value, :key => 'rval'
|
55
|
+
end
|
56
|
+
|
57
|
+
obj = CustomConnectionObject.new
|
58
|
+
|
59
|
+
obj.default_redis_value.value.should == nil
|
60
|
+
obj.redis_value.value.should == nil
|
61
|
+
|
62
|
+
obj.default_redis_value.value = 'foo'
|
63
|
+
obj.default_redis_value.value.should == 'foo'
|
64
|
+
obj.redis_value.value.should == nil
|
65
|
+
|
66
|
+
obj.default_redis_value.clear
|
67
|
+
obj.redis_value.value = 'foo'
|
68
|
+
obj.redis_value.value.should == 'foo'
|
69
|
+
obj.default_redis_value.value.should == nil
|
70
|
+
|
71
|
+
obj.redis_value.clear
|
72
|
+
obj.default_redis_value.clear
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should support local handles with a vanilla redis connection" do
|
45
76
|
Redis.current = nil # reset from other tests
|
46
77
|
Redis::Objects.redis = nil
|
47
78
|
@redis_handle = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
|
@@ -86,6 +117,51 @@ describe 'Connection tests' do
|
|
86
117
|
c.decr(1)
|
87
118
|
end
|
88
119
|
|
120
|
+
it "should support local handles with a connection_pool" do
|
121
|
+
Redis.current = nil # reset from other tests
|
122
|
+
Redis::Objects.redis = nil
|
123
|
+
@redis_handle = ConnectionPool.new { Redis.new(:host => REDIS_HOST, :port => REDIS_PORT) }
|
124
|
+
|
125
|
+
# Redis.current is lazily auto-populated to touch 6379
|
126
|
+
# This why we choose the weird 9212 port to avoid
|
127
|
+
Redis.current.inspect.should == Redis.new.inspect
|
128
|
+
Redis::Objects.redis.inspect.should == Redis.new.inspect
|
129
|
+
|
130
|
+
v = Redis::Value.new('conn/value', @redis_handle)
|
131
|
+
v.clear
|
132
|
+
v.value = 'yay'
|
133
|
+
v.value.should == 'yay'
|
134
|
+
|
135
|
+
h = Redis::HashKey.new('conn/hash', @redis_handle)
|
136
|
+
h.clear
|
137
|
+
h['k'] = 'v'
|
138
|
+
|
139
|
+
l = Redis::List.new('conn/list', @redis_handle)
|
140
|
+
l.clear
|
141
|
+
l << 3
|
142
|
+
l << 4
|
143
|
+
l << 5
|
144
|
+
|
145
|
+
s = Redis::Set.new('conn/set', @redis_handle)
|
146
|
+
s.clear
|
147
|
+
s << 5
|
148
|
+
s << 5
|
149
|
+
s << 6
|
150
|
+
s << 7
|
151
|
+
|
152
|
+
z = Redis::SortedSet.new('conn/zset', @redis_handle)
|
153
|
+
z.clear
|
154
|
+
z['a'] = 8
|
155
|
+
z['b'] = 7
|
156
|
+
z['c'] = 9
|
157
|
+
z['d'] = 6
|
158
|
+
|
159
|
+
c = Redis::Counter.new('conn/counter', @redis_handle)
|
160
|
+
c.reset
|
161
|
+
c.incr(3)
|
162
|
+
c.decr(1)
|
163
|
+
end
|
164
|
+
|
89
165
|
it "should support Redis.current" do
|
90
166
|
Redis.current = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
|
91
167
|
|
@@ -97,7 +173,41 @@ describe 'Connection tests' do
|
|
97
173
|
Redis::Counter.new('conn/counter').should == 2
|
98
174
|
end
|
99
175
|
|
100
|
-
it "should support Redis::Objects.redis=" do
|
176
|
+
it "should support Redis::Objects.redis= with a connection_pool" do
|
177
|
+
@redis_handle = ConnectionPool.new { Redis.new(:host => REDIS_HOST, :port => REDIS_PORT) }
|
178
|
+
|
179
|
+
# Redis.current is lazily auto-populated to touch 6379
|
180
|
+
# This why we choose the weird 9212 port to avoid
|
181
|
+
Redis.current = BAD_REDIS
|
182
|
+
Redis::Objects.redis.should == BAD_REDIS
|
183
|
+
|
184
|
+
# This set of tests sucks, it fucks up the per-data-type handles
|
185
|
+
# because Redis.current is then set to a BS value, and the lazy
|
186
|
+
# init code in redis-rb will keep that value until we clear it.
|
187
|
+
# This ends up fucking any sequential tests.
|
188
|
+
raises_exception{ Redis::Value.new('conn/value').should.be.nil }
|
189
|
+
raises_exception{ Redis::HashKey.new('conn/hash').keys.should == [] }
|
190
|
+
raises_exception{ Redis::List.new('conn/list').sort.should == [] }
|
191
|
+
raises_exception{ Redis::Set.new('conn/set').sort.should == [] }
|
192
|
+
raises_exception{ Redis::SortedSet.new('conn/zset').should == [] }
|
193
|
+
raises_exception{ Redis::Counter.new('conn/counter').get.should == 0 }
|
194
|
+
|
195
|
+
Redis::Objects.redis = @redis_handle
|
196
|
+
Redis::Value.new('fart').redis.is_a?(Redis::Objects::ConnectionPoolProxy).should == true
|
197
|
+
|
198
|
+
# These should now get the correct handle
|
199
|
+
Redis::Value.new('conn/value').should == 'yay'
|
200
|
+
Redis::HashKey.new('conn/hash').keys.should == ['k']
|
201
|
+
Redis::List.new('conn/list').sort.should == ['3', '4', '5']
|
202
|
+
Redis::Set.new('conn/set').sort.should == ['5', '6', '7']
|
203
|
+
Redis::SortedSet.new('conn/zset').should == ['d', 'b', 'a', 'c']
|
204
|
+
Redis::Counter.new('conn/counter').should == 2
|
205
|
+
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should support Redis::Objects.redis= with a vanilla redis connection" do
|
209
|
+
# reset redis
|
210
|
+
Redis::Objects.redis = nil
|
101
211
|
@redis_handle = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
|
102
212
|
|
103
213
|
# Redis.current is lazily auto-populated to touch 6379
|
@@ -130,5 +240,4 @@ describe 'Connection tests' do
|
|
130
240
|
# Fix for future tests
|
131
241
|
Redis.current = @redis_handle
|
132
242
|
end
|
133
|
-
|
134
243
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-objects
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Wiger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: connection_pool
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: redis-namespace
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -117,6 +131,7 @@ files:
|
|
117
131
|
- lib/redis/list.rb
|
118
132
|
- lib/redis/lock.rb
|
119
133
|
- lib/redis/objects.rb
|
134
|
+
- lib/redis/objects/connection_pool_proxy.rb
|
120
135
|
- lib/redis/objects/counters.rb
|
121
136
|
- lib/redis/objects/hashes.rb
|
122
137
|
- lib/redis/objects/lists.rb
|