cache 0.2.3 → 0.2.4
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/README.md +7 -5
- data/cache.gemspec +6 -4
- data/lib/cache/storage.rb +26 -25
- data/lib/cache/version.rb +2 -1
- data/test/shared_tests.rb +4 -4
- metadata +21 -45
data/README.md
CHANGED
@@ -2,7 +2,13 @@
|
|
2
2
|
|
3
3
|
Wraps memcached, redis, memcache-client, dalli and handles their weirdnesses, including forking.
|
4
4
|
|
5
|
-
|
5
|
+
Aims to let other libraries be cache-agnostic in return for a performance hit.
|
6
|
+
|
7
|
+
## Real world usage
|
8
|
+
|
9
|
+
Used by [lock_method](https://github.com/seamusabshere/lock_method) and [cache_method](https://github.com/seamusabshere/cache_method) so that you can use them with memcached, redis, etc.
|
10
|
+
|
11
|
+
In production use at [carbon.brighterplanet.com](http://carbon.brighterplanet.com) and [data.brighterplanet.com](http://data.brighterplanet.com).
|
6
12
|
|
7
13
|
## Quick example
|
8
14
|
|
@@ -34,10 +40,6 @@ I wanted a common interface to a bunch of great Ruby cache clients so I can deve
|
|
34
40
|
* I don't know why Memcached::Rails isn't implemented as an ActiveRecord::Cache::Store (Dalli did it just fine!)
|
35
41
|
* Why are you asking me about :raw or whatever? Just marshal it
|
36
42
|
|
37
|
-
## Real world usage
|
38
|
-
|
39
|
-
In production use at [carbon.brighterplanet.com](http://carbon.brighterplanet.com), the Brighter Planet emission estimate web service.
|
40
|
-
|
41
43
|
## Speed
|
42
44
|
|
43
45
|
It's about 50% slower than raw Memcached (if that's what you're wrapping) and barely slower at all than Dalli (if that's what you're wrapping.)
|
data/cache.gemspec
CHANGED
@@ -6,11 +6,11 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "cache"
|
7
7
|
s.version = Cache::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["Seamus Abshere"]
|
10
|
-
s.email = ["seamus@abshere.net"]
|
9
|
+
s.authors = ["Seamus Abshere","Christoph Grabo"]
|
10
|
+
s.email = ["seamus@abshere.net","chris@dinarrr.com"]
|
11
11
|
s.homepage = "https://github.com/seamusabshere/cache"
|
12
12
|
s.summary = %q{A unified cache handling interface inspired by libraries like ActiveSupport::Cache::Store, Perl's Cache::Cache, CHI, etc.}
|
13
|
-
s.description = %q{Wraps memcached, redis, memcache-client, dalli and handles their weirdnesses, including forking}
|
13
|
+
s.description = %q{Wraps memcached, redis(-namespace), memcache-client, dalli and handles their weirdnesses, including forking}
|
14
14
|
|
15
15
|
s.rubyforge_project = "cache"
|
16
16
|
|
@@ -18,13 +18,15 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
|
-
|
21
|
+
|
22
22
|
s.add_dependency 'activesupport', '>=2.3.11' # for default memory store
|
23
23
|
s.add_dependency 'i18n' # activesupport
|
24
24
|
s.add_development_dependency 'yard'
|
25
25
|
s.add_development_dependency 'test-unit'
|
26
26
|
s.add_development_dependency 'redis'
|
27
|
+
s.add_development_dependency 'redis-namespace'
|
27
28
|
s.add_development_dependency 'dalli'
|
28
29
|
s.add_development_dependency 'memcached'
|
29
30
|
s.add_development_dependency 'memcache-client'
|
30
31
|
end
|
32
|
+
|
data/lib/cache/storage.rb
CHANGED
@@ -8,7 +8,7 @@ class Cache
|
|
8
8
|
@pid = ::Process.pid
|
9
9
|
@thread_object_id = ::Thread.current.object_id
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def get(k)
|
13
13
|
reset_if_forked_or_threaded
|
14
14
|
if memcached?
|
@@ -25,7 +25,7 @@ class Cache
|
|
25
25
|
raise "Don't know how to GET with #{bare.inspect}"
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def get_multi(ks)
|
30
30
|
reset_if_forked_or_threaded
|
31
31
|
if memcached?
|
@@ -41,7 +41,7 @@ class Cache
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
def set(k, v, ttl)
|
46
46
|
reset_if_forked_or_threaded
|
47
47
|
if memcached? or dalli? or memcached_rails? or mem_cache?
|
@@ -62,7 +62,7 @@ class Cache
|
|
62
62
|
raise "Don't know how to SET with #{bare.inspect}"
|
63
63
|
end
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
def delete(k)
|
67
67
|
reset_if_forked_or_threaded
|
68
68
|
if memcached?
|
@@ -75,12 +75,12 @@ class Cache
|
|
75
75
|
raise "Don't know how to DELETE with #{bare.inspect}"
|
76
76
|
end
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
def flush
|
80
80
|
reset_if_forked_or_threaded
|
81
81
|
bare.send %w{ flush flushdb flush_all clear }.detect { |flush_cmd| bare.respond_to? flush_cmd }
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
# TODO detect nils
|
85
85
|
def exist?(k)
|
86
86
|
reset_if_forked_or_threaded
|
@@ -96,7 +96,7 @@ class Cache
|
|
96
96
|
!get(k).nil?
|
97
97
|
end
|
98
98
|
end
|
99
|
-
|
99
|
+
|
100
100
|
# TODO use native memcached increment if available
|
101
101
|
# TODO don't reset the timer!
|
102
102
|
def increment(k, amount)
|
@@ -105,17 +105,17 @@ class Cache
|
|
105
105
|
set k, new_v, 0
|
106
106
|
new_v
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
def decrement(k, amount)
|
110
110
|
# reset_if_forked_or_threaded - uses increment, which uses get
|
111
111
|
increment k, -amount
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
114
|
# TODO don't resort to trickery like this
|
115
115
|
def reset
|
116
116
|
@pid = nil
|
117
117
|
end
|
118
|
-
|
118
|
+
|
119
119
|
def fetch(k, ttl, &blk)
|
120
120
|
reset_if_forked_or_threaded
|
121
121
|
if dalli? or mem_cache?
|
@@ -132,7 +132,7 @@ class Cache
|
|
132
132
|
end
|
133
133
|
end
|
134
134
|
end
|
135
|
-
|
135
|
+
|
136
136
|
def cas(k, ttl, &blk)
|
137
137
|
reset_if_forked_or_threaded
|
138
138
|
if memcached?
|
@@ -146,7 +146,7 @@ class Cache
|
|
146
146
|
new_v
|
147
147
|
end
|
148
148
|
end
|
149
|
-
|
149
|
+
|
150
150
|
def stats
|
151
151
|
reset_if_forked_or_threaded
|
152
152
|
if bare.respond_to?(:stats)
|
@@ -155,13 +155,13 @@ class Cache
|
|
155
155
|
{}
|
156
156
|
end
|
157
157
|
end
|
158
|
-
|
158
|
+
|
159
159
|
private
|
160
|
-
|
160
|
+
|
161
161
|
def bare
|
162
162
|
@bare ||= parent.config.client
|
163
163
|
end
|
164
|
-
|
164
|
+
|
165
165
|
def reset_if_forked_or_threaded
|
166
166
|
if fork_detected?
|
167
167
|
# $stderr.puts "fork detected" if ENV['CACHE_DEBUG'] == 'true'
|
@@ -187,47 +187,47 @@ class Cache
|
|
187
187
|
end
|
188
188
|
end
|
189
189
|
end
|
190
|
-
|
190
|
+
|
191
191
|
def fork_detected?
|
192
192
|
if @pid != ::Process.pid
|
193
193
|
@pid = ::Process.pid
|
194
194
|
end
|
195
195
|
end
|
196
|
-
|
196
|
+
|
197
197
|
def new_thread_detected?
|
198
198
|
if @thread_object_id != ::Thread.current.object_id
|
199
199
|
@thread_object_id = ::Thread.current.object_id
|
200
200
|
end
|
201
201
|
end
|
202
|
-
|
202
|
+
|
203
203
|
def dalli?
|
204
204
|
return @dalli_query[0] if @dalli_query.is_a?(::Array)
|
205
205
|
answer = (defined?(::Dalli) and bare.is_a?(::Dalli::Client))
|
206
206
|
@dalli_query = [answer]
|
207
207
|
answer
|
208
208
|
end
|
209
|
-
|
209
|
+
|
210
210
|
def active_support_store?
|
211
211
|
return @active_support_store_query[0] if @active_support_store_query.is_a?(::Array)
|
212
212
|
answer = (defined?(::ActiveSupport::Cache) and bare.is_a?(::ActiveSupport::Cache::Store))
|
213
213
|
@active_support_store_query = [answer]
|
214
214
|
answer
|
215
215
|
end
|
216
|
-
|
216
|
+
|
217
217
|
def dalli_store?
|
218
218
|
return @dalli_store_query[0] if @dalli_store_query.is_a?(::Array)
|
219
219
|
answer = (defined?(::ActiveSupport::Cache::DalliStore) and bare.is_a?(::ActiveSupport::Cache::DalliStore))
|
220
220
|
@dalli_store_query = [answer]
|
221
221
|
answer
|
222
222
|
end
|
223
|
-
|
223
|
+
|
224
224
|
def memory_store?
|
225
225
|
return @memory_store_query[0] if @memory_store_query.is_a?(::Array)
|
226
226
|
answer = (defined?(::ActiveSupport::Cache::MemoryStore) and bare.is_a?(::ActiveSupport::Cache::MemoryStore))
|
227
227
|
@memory_store_query = [answer]
|
228
228
|
answer
|
229
229
|
end
|
230
|
-
|
230
|
+
|
231
231
|
def mem_cache?
|
232
232
|
return @mem_cache_query[0] if @mem_cache_query.is_a?(::Array)
|
233
233
|
answer = (defined?(::MemCache) and bare.is_a?(::MemCache))
|
@@ -241,19 +241,20 @@ class Cache
|
|
241
241
|
@memcached_query = [answer]
|
242
242
|
answer
|
243
243
|
end
|
244
|
-
|
244
|
+
|
245
245
|
def memcached_rails?
|
246
246
|
return @memcached_rails_query[0] if @memcached_rails_query.is_a?(::Array)
|
247
247
|
answer = (defined?(::Memcached) and bare.is_a?(::Memcached::Rails))
|
248
248
|
@memcached_rails_query = [answer]
|
249
249
|
answer
|
250
250
|
end
|
251
|
-
|
251
|
+
|
252
252
|
def redis?
|
253
253
|
return @redis_query[0] if @redis_query.is_a?(::Array)
|
254
|
-
answer = (defined?(::Redis) and bare.is_a?(::Redis))
|
254
|
+
answer = (defined?(::Redis) and bare.is_a?(::Redis)) || (defined?(::Redis::Namespace) and bare.is_a?(::Redis::Namespace))
|
255
255
|
@redis_query = [answer]
|
256
256
|
answer
|
257
257
|
end
|
258
258
|
end
|
259
259
|
end
|
260
|
+
|
data/lib/cache/version.rb
CHANGED
data/test/shared_tests.rb
CHANGED
@@ -121,17 +121,17 @@ module SharedTests
|
|
121
121
|
|
122
122
|
def test_increment
|
123
123
|
assert !@cache.exist?('high-fives')
|
124
|
-
@cache.increment
|
124
|
+
assert_equal 1, @cache.increment('high-fives')
|
125
125
|
assert_equal 1, @cache.get('high-fives')
|
126
|
-
@cache.increment
|
126
|
+
assert_equal 2, @cache.increment('high-fives')
|
127
127
|
assert_equal 2, @cache.get('high-fives')
|
128
128
|
end
|
129
129
|
|
130
130
|
def test_decrement
|
131
131
|
assert !@cache.exist?('high-fives')
|
132
|
-
@cache.decrement
|
132
|
+
assert_equal -1, @cache.decrement('high-fives')
|
133
133
|
assert_equal -1, @cache.get('high-fives')
|
134
|
-
@cache.decrement
|
134
|
+
assert_equal -2, @cache.decrement('high-fives')
|
135
135
|
assert_equal -2, @cache.get('high-fives')
|
136
136
|
end
|
137
137
|
|
metadata
CHANGED
@@ -1,21 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 2
|
9
|
-
- 3
|
10
|
-
version: 0.2.3
|
4
|
+
prerelease:
|
5
|
+
version: 0.2.4
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Seamus Abshere
|
9
|
+
- Christoph Grabo
|
14
10
|
autorequire:
|
15
11
|
bindir: bin
|
16
12
|
cert_chain: []
|
17
13
|
|
18
|
-
date: 2011-
|
14
|
+
date: 2011-05-08 00:00:00 -05:00
|
19
15
|
default_executable:
|
20
16
|
dependencies:
|
21
17
|
- !ruby/object:Gem::Dependency
|
@@ -26,11 +22,6 @@ dependencies:
|
|
26
22
|
requirements:
|
27
23
|
- - ">="
|
28
24
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 21
|
30
|
-
segments:
|
31
|
-
- 2
|
32
|
-
- 3
|
33
|
-
- 11
|
34
25
|
version: 2.3.11
|
35
26
|
type: :runtime
|
36
27
|
version_requirements: *id001
|
@@ -42,9 +33,6 @@ dependencies:
|
|
42
33
|
requirements:
|
43
34
|
- - ">="
|
44
35
|
- !ruby/object:Gem::Version
|
45
|
-
hash: 3
|
46
|
-
segments:
|
47
|
-
- 0
|
48
36
|
version: "0"
|
49
37
|
type: :runtime
|
50
38
|
version_requirements: *id002
|
@@ -56,9 +44,6 @@ dependencies:
|
|
56
44
|
requirements:
|
57
45
|
- - ">="
|
58
46
|
- !ruby/object:Gem::Version
|
59
|
-
hash: 3
|
60
|
-
segments:
|
61
|
-
- 0
|
62
47
|
version: "0"
|
63
48
|
type: :development
|
64
49
|
version_requirements: *id003
|
@@ -70,9 +55,6 @@ dependencies:
|
|
70
55
|
requirements:
|
71
56
|
- - ">="
|
72
57
|
- !ruby/object:Gem::Version
|
73
|
-
hash: 3
|
74
|
-
segments:
|
75
|
-
- 0
|
76
58
|
version: "0"
|
77
59
|
type: :development
|
78
60
|
version_requirements: *id004
|
@@ -84,57 +66,57 @@ dependencies:
|
|
84
66
|
requirements:
|
85
67
|
- - ">="
|
86
68
|
- !ruby/object:Gem::Version
|
87
|
-
hash: 3
|
88
|
-
segments:
|
89
|
-
- 0
|
90
69
|
version: "0"
|
91
70
|
type: :development
|
92
71
|
version_requirements: *id005
|
93
72
|
- !ruby/object:Gem::Dependency
|
94
|
-
name:
|
73
|
+
name: redis-namespace
|
95
74
|
prerelease: false
|
96
75
|
requirement: &id006 !ruby/object:Gem::Requirement
|
97
76
|
none: false
|
98
77
|
requirements:
|
99
78
|
- - ">="
|
100
79
|
- !ruby/object:Gem::Version
|
101
|
-
hash: 3
|
102
|
-
segments:
|
103
|
-
- 0
|
104
80
|
version: "0"
|
105
81
|
type: :development
|
106
82
|
version_requirements: *id006
|
107
83
|
- !ruby/object:Gem::Dependency
|
108
|
-
name:
|
84
|
+
name: dalli
|
109
85
|
prerelease: false
|
110
86
|
requirement: &id007 !ruby/object:Gem::Requirement
|
111
87
|
none: false
|
112
88
|
requirements:
|
113
89
|
- - ">="
|
114
90
|
- !ruby/object:Gem::Version
|
115
|
-
hash: 3
|
116
|
-
segments:
|
117
|
-
- 0
|
118
91
|
version: "0"
|
119
92
|
type: :development
|
120
93
|
version_requirements: *id007
|
121
94
|
- !ruby/object:Gem::Dependency
|
122
|
-
name:
|
95
|
+
name: memcached
|
123
96
|
prerelease: false
|
124
97
|
requirement: &id008 !ruby/object:Gem::Requirement
|
125
98
|
none: false
|
126
99
|
requirements:
|
127
100
|
- - ">="
|
128
101
|
- !ruby/object:Gem::Version
|
129
|
-
hash: 3
|
130
|
-
segments:
|
131
|
-
- 0
|
132
102
|
version: "0"
|
133
103
|
type: :development
|
134
104
|
version_requirements: *id008
|
135
|
-
|
105
|
+
- !ruby/object:Gem::Dependency
|
106
|
+
name: memcache-client
|
107
|
+
prerelease: false
|
108
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: "0"
|
114
|
+
type: :development
|
115
|
+
version_requirements: *id009
|
116
|
+
description: Wraps memcached, redis(-namespace), memcache-client, dalli and handles their weirdnesses, including forking
|
136
117
|
email:
|
137
118
|
- seamus@abshere.net
|
119
|
+
- chris@dinarrr.com
|
138
120
|
executables: []
|
139
121
|
|
140
122
|
extensions: []
|
@@ -180,23 +162,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
180
162
|
requirements:
|
181
163
|
- - ">="
|
182
164
|
- !ruby/object:Gem::Version
|
183
|
-
hash: 3
|
184
|
-
segments:
|
185
|
-
- 0
|
186
165
|
version: "0"
|
187
166
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
167
|
none: false
|
189
168
|
requirements:
|
190
169
|
- - ">="
|
191
170
|
- !ruby/object:Gem::Version
|
192
|
-
hash: 3
|
193
|
-
segments:
|
194
|
-
- 0
|
195
171
|
version: "0"
|
196
172
|
requirements: []
|
197
173
|
|
198
174
|
rubyforge_project: cache
|
199
|
-
rubygems_version: 1.
|
175
|
+
rubygems_version: 1.6.2
|
200
176
|
signing_key:
|
201
177
|
specification_version: 3
|
202
178
|
summary: A unified cache handling interface inspired by libraries like ActiveSupport::Cache::Store, Perl's Cache::Cache, CHI, etc.
|