cache 0.2.7 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,7 +10,7 @@ class TestMemcachedRailsStorage < Test::Unit::TestCase
10
10
  include SharedTests
11
11
 
12
12
  def get_bare_id
13
- @cache.storage.send(:bare).object_id
13
+ @cache.thread_metal.object_id
14
14
  end
15
15
 
16
16
  def test_treats_as_not_thread_safe
@@ -10,7 +10,7 @@ class TestMemcachedStorage < Test::Unit::TestCase
10
10
  include SharedTests
11
11
 
12
12
  def get_bare_id
13
- @cache.storage.send(:bare).object_id
13
+ @cache.thread_metal.object_id
14
14
  end
15
15
 
16
16
  def test_treats_as_not_thread_safe
@@ -29,6 +29,9 @@ class TestMemcachedStorage < Test::Unit::TestCase
29
29
 
30
30
  # make sure the bare client was reinitialized
31
31
  assert(main_thread_bare_id != new_thread_bare_id)
32
+
33
+ # make sure the main thread's client wasn't messed with
34
+ assert_equal main_thread_bare_id, get_bare_id
32
35
  end
33
36
 
34
37
  def test_treats_as_not_fork_safe
@@ -1,5 +1,6 @@
1
1
  require 'helper'
2
2
 
3
+ require 'memcached'
3
4
  require 'active_support/cache'
4
5
  require 'active_support/cache/memory_store'
5
6
 
@@ -8,7 +9,7 @@ class TestRailsCacheStorage < Test::Unit::TestCase
8
9
  eval %{
9
10
  module ::Rails
10
11
  def self.cache
11
- @cache || :deadbeef
12
+ @cache || Memcached::Rails.new('localhost:11211', :support_cas => true)
12
13
  end
13
14
  def self.cache=(foo)
14
15
  @cache = foo
@@ -22,44 +23,45 @@ class TestRailsCacheStorage < Test::Unit::TestCase
22
23
  end
23
24
 
24
25
  def test_defaults_to_rails_cache
25
- assert_equal :deadbeef, Cache.new.config.client
26
+ assert_equal Memcached::Rails, Cache.new.metal.class
26
27
  end
27
28
 
28
29
  def test_helpful_default
30
+ eval %{
31
+ module ::Rails
32
+ def self.cache
33
+ @cache
34
+ end
35
+ end
36
+ }
29
37
  Rails.cache = Cache.new
30
- assert_equal ActiveSupport::Cache::MemoryStore, Rails.cache.config.client.class
38
+ assert_equal ActiveSupport::Cache::MemoryStore, Rails.cache.metal.class
31
39
  end
32
40
 
33
41
  def test_explicitly_set
34
42
  c = Cache.new(Rails.cache)
35
- assert_equal :deadbeef, c.config.client
36
- end
37
-
38
- def test_explicitly_set_2
39
- c = Cache.new
40
- c.config.client = Rails.cache
41
- assert_equal :deadbeef, c.config.client
43
+ assert_equal Memcached::Rails, c.metal.class
42
44
  end
43
45
 
44
- # these behave strangely because they resolve the value of Rails.cache (e.g., :deadbeef) before returning
46
+ # these behave strangely because they resolve the value of Rails.cache (e.g., Memcached::Rails) before returning
45
47
  def test_silly_self_reference
46
48
  Rails.cache = Cache.new(Rails.cache)
47
- assert_equal :deadbeef, Rails.cache.config.client
49
+ assert_equal Memcached::Rails, Rails.cache.metal.class
48
50
  end
49
51
 
50
52
  def test_self_reference_twice
51
53
  Rails.cache = Cache.new(Cache.new)
52
- assert_equal :deadbeef, Rails.cache.config.client
54
+ assert_equal Memcached::Rails, Rails.cache.metal.class
53
55
  end
54
56
 
55
57
  def test_self_reference_with_wrap
56
58
  Rails.cache = Cache.wrap(Cache.new)
57
- assert_equal :deadbeef, Rails.cache.config.client
59
+ assert_equal Memcached::Rails, Rails.cache.metal.class
58
60
  end
59
61
 
60
62
  def test_self_reference_with_absurd_wrapping
61
63
  Rails.cache = Cache.new(Cache.wrap(Cache.new))
62
- assert_equal :deadbeef, Rails.cache.config.client
64
+ assert_equal Memcached::Rails, Rails.cache.metal.class
63
65
  end
64
66
  #--
65
67
  end
@@ -14,7 +14,7 @@ if ENV['REDIS_URL']
14
14
 
15
15
  # client DOT client
16
16
  def get_redis_client_connection_socket_id
17
- connection = @cache.config.client.client.instance_variable_get :@connection
17
+ connection = @cache.metal.client.instance_variable_get :@connection
18
18
  sock = connection.instance_variable_get(:@sock)
19
19
  # $stderr.puts sock.inspect
20
20
  sock.object_id
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-04-03 00:00:00.000000000 Z
13
+ date: 2012-04-06 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -44,134 +44,6 @@ dependencies:
44
44
  - - ! '>='
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
- - !ruby/object:Gem::Dependency
48
- name: yard
49
- requirement: !ruby/object:Gem::Requirement
50
- none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- type: :development
56
- prerelease: false
57
- version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
- requirements:
60
- - - ! '>='
61
- - !ruby/object:Gem::Version
62
- version: '0'
63
- - !ruby/object:Gem::Dependency
64
- name: test-unit
65
- requirement: !ruby/object:Gem::Requirement
66
- none: false
67
- requirements:
68
- - - ! '>='
69
- - !ruby/object:Gem::Version
70
- version: '0'
71
- type: :development
72
- prerelease: false
73
- version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
- requirements:
76
- - - ! '>='
77
- - !ruby/object:Gem::Version
78
- version: '0'
79
- - !ruby/object:Gem::Dependency
80
- name: redis
81
- requirement: !ruby/object:Gem::Requirement
82
- none: false
83
- requirements:
84
- - - ! '>='
85
- - !ruby/object:Gem::Version
86
- version: '0'
87
- type: :development
88
- prerelease: false
89
- version_requirements: !ruby/object:Gem::Requirement
90
- none: false
91
- requirements:
92
- - - ! '>='
93
- - !ruby/object:Gem::Version
94
- version: '0'
95
- - !ruby/object:Gem::Dependency
96
- name: redis-namespace
97
- requirement: !ruby/object:Gem::Requirement
98
- none: false
99
- requirements:
100
- - - ! '>='
101
- - !ruby/object:Gem::Version
102
- version: '0'
103
- type: :development
104
- prerelease: false
105
- version_requirements: !ruby/object:Gem::Requirement
106
- none: false
107
- requirements:
108
- - - ! '>='
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: dalli
113
- requirement: !ruby/object:Gem::Requirement
114
- none: false
115
- requirements:
116
- - - ! '>='
117
- - !ruby/object:Gem::Version
118
- version: '0'
119
- type: :development
120
- prerelease: false
121
- version_requirements: !ruby/object:Gem::Requirement
122
- none: false
123
- requirements:
124
- - - ! '>='
125
- - !ruby/object:Gem::Version
126
- version: '0'
127
- - !ruby/object:Gem::Dependency
128
- name: memcached
129
- requirement: !ruby/object:Gem::Requirement
130
- none: false
131
- requirements:
132
- - - ! '>='
133
- - !ruby/object:Gem::Version
134
- version: '0'
135
- type: :development
136
- prerelease: false
137
- version_requirements: !ruby/object:Gem::Requirement
138
- none: false
139
- requirements:
140
- - - ! '>='
141
- - !ruby/object:Gem::Version
142
- version: '0'
143
- - !ruby/object:Gem::Dependency
144
- name: memcache-client
145
- requirement: !ruby/object:Gem::Requirement
146
- none: false
147
- requirements:
148
- - - ! '>='
149
- - !ruby/object:Gem::Version
150
- version: '0'
151
- type: :development
152
- prerelease: false
153
- version_requirements: !ruby/object:Gem::Requirement
154
- none: false
155
- requirements:
156
- - - ! '>='
157
- - !ruby/object:Gem::Version
158
- version: '0'
159
- - !ruby/object:Gem::Dependency
160
- name: rake
161
- requirement: !ruby/object:Gem::Requirement
162
- none: false
163
- requirements:
164
- - - ! '>='
165
- - !ruby/object:Gem::Version
166
- version: '0'
167
- type: :development
168
- prerelease: false
169
- version_requirements: !ruby/object:Gem::Requirement
170
- none: false
171
- requirements:
172
- - - ! '>='
173
- - !ruby/object:Gem::Version
174
- version: '0'
175
47
  description: Wraps memcached, redis(-namespace), memcache-client, dalli and handles
176
48
  their weirdnesses, including forking
177
49
  email:
@@ -185,6 +57,8 @@ files:
185
57
  - Gemfile
186
58
  - README.md
187
59
  - Rakefile
60
+ - benchmarks/afterrefactor.txt
61
+ - benchmarks/midrefactor.txt
188
62
  - benchmarks/v0.0.2.txt
189
63
  - benchmarks/v0.0.3.txt
190
64
  - benchmarks/v0.1.2.txt
@@ -192,8 +66,16 @@ files:
192
66
  - benchmarks/v0.2.2.txt
193
67
  - cache.gemspec
194
68
  - lib/cache.rb
69
+ - lib/cache/active_support_cache_dalli_store.rb
70
+ - lib/cache/active_support_cache_memory_store.rb
71
+ - lib/cache/active_support_cache_store.rb
195
72
  - lib/cache/config.rb
196
- - lib/cache/storage.rb
73
+ - lib/cache/dalli_client.rb
74
+ - lib/cache/mem_cache.rb
75
+ - lib/cache/memcached.rb
76
+ - lib/cache/memcached_rails.rb
77
+ - lib/cache/redis.rb
78
+ - lib/cache/redis_namespace.rb
197
79
  - lib/cache/version.rb
198
80
  - test/helper.rb
199
81
  - test/profile/benchmark.rb
data/lib/cache/storage.rb DELETED
@@ -1,260 +0,0 @@
1
- class Cache
2
- class Storage #:nodoc: all
3
-
4
- attr_reader :parent
5
-
6
- def initialize(parent)
7
- @parent = parent
8
- @pid = ::Process.pid
9
- @thread_object_id = ::Thread.current.object_id
10
- end
11
-
12
- def get(k)
13
- reset_if_forked_or_threaded
14
- if memcached?
15
- begin; bare.get(k); rescue ::Memcached::NotFound; nil; end
16
- elsif dalli? or memcached_rails? or mem_cache?
17
- bare.get k
18
- elsif redis?
19
- if cached_v = bare.get(k) and cached_v.is_a?(::String)
20
- ::Marshal.load cached_v
21
- end
22
- elsif active_support_store? or dalli_store?
23
- bare.read k
24
- else
25
- raise "Don't know how to GET with #{bare.inspect}"
26
- end
27
- end
28
-
29
- def get_multi(ks)
30
- reset_if_forked_or_threaded
31
- if memcached?
32
- bare.get ks
33
- elsif memcached_rails? or dalli? or mem_cache?
34
- bare.get_multi ks
35
- elsif active_support_store? or dalli_store?
36
- bare.read_multi *ks
37
- else
38
- ks.inject({}) do |memo, k|
39
- memo[k] = get k if exist? k
40
- memo
41
- end
42
- end
43
- end
44
-
45
- def set(k, v, ttl)
46
- reset_if_forked_or_threaded
47
- if memcached? or dalli? or memcached_rails? or mem_cache?
48
- bare.set k, v, ttl
49
- elsif redis?
50
- if ttl == 0
51
- bare.set k, ::Marshal.dump(v)
52
- else
53
- bare.setex k, ttl, ::Marshal.dump(v)
54
- end
55
- elsif active_support_store? or dalli_store?
56
- if ttl == 0
57
- bare.write k, v # never expire
58
- else
59
- bare.write k, v, :expires_in => ttl
60
- end
61
- else
62
- raise "Don't know how to SET with #{bare.inspect}"
63
- end
64
- end
65
-
66
- def delete(k)
67
- reset_if_forked_or_threaded
68
- if memcached?
69
- begin; bare.delete(k); rescue ::Memcached::NotFound; nil; end
70
- elsif redis?
71
- bare.del k
72
- elsif dalli? or memcached_rails? or mem_cache? or active_support_store? or dalli_store?
73
- bare.delete k
74
- else
75
- raise "Don't know how to DELETE with #{bare.inspect}"
76
- end
77
- end
78
-
79
- def flush
80
- reset_if_forked_or_threaded
81
- bare.send %w{ flush flushdb flush_all clear }.detect { |flush_cmd| bare.respond_to? flush_cmd }
82
- end
83
-
84
- # TODO detect nils
85
- def exist?(k)
86
- reset_if_forked_or_threaded
87
- if memcached?
88
- begin; bare.get(k); true; rescue ::Memcached::NotFound; false; end
89
- elsif redis?
90
- bare.exists k
91
- elsif bare.respond_to?(:exist?)
92
- # slow because we're looking it up
93
- bare.exist? k
94
- else
95
- # weak because it doesn't detect keys that equal nil
96
- !get(k).nil?
97
- end
98
- end
99
-
100
- # TODO use native memcached increment if available
101
- # TODO don't reset the timer!
102
- def increment(k, amount)
103
- # reset_if_forked_or_threaded - uses get
104
- new_v = get(k).to_i + amount
105
- set k, new_v, 0
106
- new_v
107
- end
108
-
109
- def decrement(k, amount)
110
- # reset_if_forked_or_threaded - uses increment, which uses get
111
- increment k, -amount
112
- end
113
-
114
- # TODO don't resort to trickery like this
115
- def reset
116
- @pid = nil
117
- end
118
-
119
- def fetch(k, ttl, &blk)
120
- reset_if_forked_or_threaded
121
- if dalli? or mem_cache?
122
- bare.fetch k, ttl, &blk
123
- elsif active_support_store?
124
- bare.fetch k, { :expires_in => ttl }, &blk
125
- else
126
- if exist? k
127
- get k
128
- elsif blk
129
- v = blk.call
130
- set k, v, ttl
131
- v
132
- end
133
- end
134
- end
135
-
136
- def cas(k, ttl, &blk)
137
- reset_if_forked_or_threaded
138
- if memcached?
139
- begin; bare.cas(k, ttl, &blk); rescue ::Memcached::NotFound; nil; end
140
- elsif dalli? or memcached_rails?
141
- bare.cas k, ttl, &blk
142
- elsif blk and exist?(k)
143
- old_v = get k
144
- new_v = blk.call old_v
145
- set k, new_v, ttl
146
- new_v
147
- end
148
- end
149
-
150
- def stats
151
- reset_if_forked_or_threaded
152
- if bare.respond_to?(:stats)
153
- bare.stats
154
- else
155
- {}
156
- end
157
- end
158
-
159
- private
160
-
161
- def bare
162
- @bare ||= parent.config.client
163
- end
164
-
165
- def reset_if_forked_or_threaded
166
- if fork_detected?
167
- # $stderr.puts "fork detected" if ENV['CACHE_DEBUG'] == 'true'
168
- if dalli?
169
- parent.config.client.close
170
- elsif dalli_store?
171
- parent.config.client.reset
172
- elsif memcached? or memcached_rails?
173
- cloned_client = parent.config.client.clone
174
- parent.config.client = cloned_client
175
- @bare = parent.config.client
176
- elsif redis?
177
- parent.config.client.client.connect
178
- elsif mem_cache?
179
- parent.config.client.reset
180
- end
181
- elsif new_thread_detected?
182
- # $stderr.puts "new thread detected" if ENV['CACHE_DEBUG'] == 'true'
183
- if memcached? or memcached_rails?
184
- cloned_client = parent.config.client.clone
185
- parent.config.client = cloned_client
186
- @bare = parent.config.client
187
- end
188
- end
189
- end
190
-
191
- def fork_detected?
192
- if @pid != ::Process.pid
193
- @pid = ::Process.pid
194
- end
195
- end
196
-
197
- def new_thread_detected?
198
- if @thread_object_id != ::Thread.current.object_id
199
- @thread_object_id = ::Thread.current.object_id
200
- end
201
- end
202
-
203
- def dalli?
204
- return @dalli_query[0] if @dalli_query.is_a?(::Array)
205
- answer = (defined?(::Dalli) and bare.is_a?(::Dalli::Client))
206
- @dalli_query = [answer]
207
- answer
208
- end
209
-
210
- def active_support_store?
211
- return @active_support_store_query[0] if @active_support_store_query.is_a?(::Array)
212
- answer = (defined?(::ActiveSupport::Cache) and bare.is_a?(::ActiveSupport::Cache::Store))
213
- @active_support_store_query = [answer]
214
- answer
215
- end
216
-
217
- def dalli_store?
218
- return @dalli_store_query[0] if @dalli_store_query.is_a?(::Array)
219
- answer = (defined?(::ActiveSupport::Cache::DalliStore) and bare.is_a?(::ActiveSupport::Cache::DalliStore))
220
- @dalli_store_query = [answer]
221
- answer
222
- end
223
-
224
- def memory_store?
225
- return @memory_store_query[0] if @memory_store_query.is_a?(::Array)
226
- answer = (defined?(::ActiveSupport::Cache::MemoryStore) and bare.is_a?(::ActiveSupport::Cache::MemoryStore))
227
- @memory_store_query = [answer]
228
- answer
229
- end
230
-
231
- def mem_cache?
232
- return @mem_cache_query[0] if @mem_cache_query.is_a?(::Array)
233
- answer = (defined?(::MemCache) and bare.is_a?(::MemCache))
234
- @mem_cache_query = [answer]
235
- answer
236
- end
237
-
238
- def memcached?
239
- return @memcached_query[0] if @memcached_query.is_a?(::Array)
240
- answer = (defined?(::Memcached) and bare.is_a?(::Memcached) and not bare.is_a?(::Memcached::Rails))
241
- @memcached_query = [answer]
242
- answer
243
- end
244
-
245
- def memcached_rails?
246
- return @memcached_rails_query[0] if @memcached_rails_query.is_a?(::Array)
247
- answer = (defined?(::Memcached) and bare.is_a?(::Memcached::Rails))
248
- @memcached_rails_query = [answer]
249
- answer
250
- end
251
-
252
- def redis?
253
- return @redis_query[0] if @redis_query.is_a?(::Array)
254
- answer = (defined?(::Redis) and bare.is_a?(::Redis)) || (defined?(::Redis::Namespace) and bare.is_a?(::Redis::Namespace))
255
- @redis_query = [answer]
256
- answer
257
- end
258
- end
259
- end
260
-