cached_model 1.2.1 → 1.3.1
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/History.txt +30 -0
- data/{LICENSE → LICENSE.txt} +0 -0
- data/Manifest.txt +3 -2
- data/{README → README.txt} +6 -24
- data/Rakefile +16 -56
- data/lib/cached_model.rb +57 -19
- data/test/test_cached_model.rb +162 -55
- metadata +41 -11
data/History.txt
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
= 1.3.1
|
2
|
+
|
3
|
+
* Match behavior of ActiveRecord::Base#transaction
|
4
|
+
|
5
|
+
= 1.3.0
|
6
|
+
|
7
|
+
* Added support for transaction
|
8
|
+
* Use ZenTest's assertions
|
9
|
+
* Switched to Hoe
|
10
|
+
|
11
|
+
= 1.2.1
|
12
|
+
|
13
|
+
* Lost to time
|
14
|
+
|
15
|
+
= 1.2.0
|
16
|
+
|
17
|
+
* Support Rails 1.1.2+
|
18
|
+
* Moved work into find_by_sql
|
19
|
+
|
20
|
+
= 1.1.0
|
21
|
+
|
22
|
+
* Lost to time
|
23
|
+
|
24
|
+
= 1.0.1
|
25
|
+
|
26
|
+
* Lost to time
|
27
|
+
|
28
|
+
= 1.0.0
|
29
|
+
|
30
|
+
* Birthday!
|
data/{LICENSE → LICENSE.txt}
RENAMED
File without changes
|
data/Manifest.txt
CHANGED
data/{README → README.txt}
RENAMED
@@ -34,31 +34,13 @@ First, install the cached_model gem:
|
|
34
34
|
|
35
35
|
$ sudo gem install cached_model
|
36
36
|
|
37
|
-
Then set up memcache-client
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
:c_threshold => 10_000,
|
42
|
-
:compression => true,
|
43
|
-
:debug => false,
|
44
|
-
:namespace => 'my_rails_app',
|
45
|
-
:readonly => false,
|
46
|
-
:urlencode => false
|
47
|
-
}
|
48
|
-
|
49
|
-
CACHE = MemCache.new memcache_options
|
50
|
-
CACHE.servers = 'localhost:11211'
|
51
|
-
|
52
|
-
session_options = {
|
53
|
-
:database_manager => CGI::Session::MemCacheStore,
|
54
|
-
:cache => CACHE,
|
55
|
-
:session_domain => 'trackmap.robotcoop.com'
|
56
|
-
}
|
57
|
-
|
58
|
-
ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.update session_options
|
37
|
+
Then set up memcache-client for CachedModel by setting CACHE in your
|
38
|
+
config/environment files:
|
39
|
+
|
40
|
+
CACHE = MemCache.new 'localhost:11211', :namespace => 'my_rails_app'
|
59
41
|
|
60
|
-
You will need separate namespaces for production and development, if
|
61
|
-
memcache on the same machine.
|
42
|
+
You will need separate namespaces for production and development, if
|
43
|
+
you are using memcache on the same machine.
|
62
44
|
|
63
45
|
Note that using memcache with tests will cause test failures, so set your
|
64
46
|
memcache to be readonly for the test environment.
|
data/Rakefile
CHANGED
@@ -1,65 +1,25 @@
|
|
1
|
-
|
2
|
-
require 'rake'
|
3
|
-
require 'rake/testtask'
|
4
|
-
require 'rake/rdoctask'
|
5
|
-
require 'rake/gempackagetask'
|
6
|
-
|
7
|
-
$VERBOSE = nil
|
1
|
+
# vim: syntax=Ruby
|
8
2
|
|
9
|
-
|
10
|
-
s.name = 'cached_model'
|
11
|
-
s.version = '1.2.1'
|
12
|
-
s.summary = 'An ActiveRecord::Base model that caches records'
|
13
|
-
s.authors = 'Robert Cottrell, Eric Hodel'
|
14
|
-
s.email = 'bob@robotcoop.com'
|
3
|
+
require 'hoe'
|
15
4
|
|
16
|
-
|
17
|
-
s.files = File.read('Manifest.txt').split($/)
|
18
|
-
s.require_path = 'lib'
|
5
|
+
DEV_DOC_PATH = 'Libraries/cached_model'
|
19
6
|
|
20
|
-
|
21
|
-
|
7
|
+
hoe = Hoe.new 'cached_model', '1.3.1' do |p|
|
8
|
+
p.summary = 'An ActiveRecord abstract model that caches records in memcached'
|
9
|
+
p.description = 'CachedModel caches simple (by id) finds in memcached reducing the amount of work the database needs to perform for simple queries.'
|
10
|
+
p.author = ['Eric Hodel', 'Robert Cottrell']
|
11
|
+
p.email = 'eric@robotcoop.com'
|
12
|
+
p.url = "http://dev.robotcoop.com/#{DEV_DOC_PATH}"
|
13
|
+
p.rubyforge_name = 'rctools'
|
22
14
|
|
23
|
-
|
24
|
-
task :default => [ :test ]
|
15
|
+
p.changes = File.read('History.txt').scan(/\A(=.*?)^=/m).first.first
|
25
16
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
t.verbose = true
|
17
|
+
p.extra_deps << ['memcache-client', '>= 1.1.0']
|
18
|
+
p.extra_deps << ['activerecord', '>= 1.14.4']
|
19
|
+
p.extra_deps << ['ZenTest', '>= 3.4.1']
|
30
20
|
end
|
31
21
|
|
32
|
-
|
33
|
-
task :update_manifest do
|
34
|
-
sh "find . -type f | sed -e 's%./%%' | egrep -v 'svn|swp|~' | egrep -v '^(doc|pkg)/' | sort > Manifest.txt"
|
35
|
-
end
|
22
|
+
SPEC = hoe.spec
|
36
23
|
|
37
|
-
|
38
|
-
Rake::RDocTask.new :rdoc do |rd|
|
39
|
-
rd.rdoc_dir = 'doc'
|
40
|
-
rd.rdoc_files.add 'lib', 'README', 'LICENSE'
|
41
|
-
rd.main = 'README'
|
42
|
-
rd.options << '-d' if `which dot` =~ /\/dot/
|
43
|
-
end
|
44
|
-
|
45
|
-
desc 'Generate RDoc for dev.robotcoop.com'
|
46
|
-
Rake::RDocTask.new :dev_rdoc do |rd|
|
47
|
-
rd.rdoc_dir = '../../../www/trunk/dev/html/Libraries/cached_model'
|
48
|
-
rd.rdoc_files.add 'lib', 'README', 'LICENSE'
|
49
|
-
rd.main = 'README'
|
50
|
-
rd.options << '-d' if `which dot` =~ /\/dot/
|
51
|
-
end
|
52
|
-
|
53
|
-
desc 'Build Gem'
|
54
|
-
Rake::GemPackageTask.new spec do |pkg|
|
55
|
-
pkg.need_tar = true
|
56
|
-
end
|
57
|
-
|
58
|
-
desc 'Clean up'
|
59
|
-
task :clean => [ :clobber_rdoc, :clobber_package ]
|
60
|
-
|
61
|
-
desc 'Clean up'
|
62
|
-
task :clobber => [ :clean ]
|
63
|
-
|
64
|
-
# vim: syntax=Ruby
|
24
|
+
require '../tasks'
|
65
25
|
|
data/lib/cached_model.rb
CHANGED
@@ -20,18 +20,34 @@ require 'memcache_util' unless $TESTING_CM
|
|
20
20
|
|
21
21
|
class CachedModel < ActiveRecord::Base
|
22
22
|
|
23
|
+
@cache_delay_commit = {}
|
23
24
|
@cache_local = {}
|
25
|
+
@cache_transaction_level = 0
|
24
26
|
@use_local_cache = false
|
25
27
|
@use_memcache = true
|
26
28
|
@ttl = 60 * 15
|
27
29
|
|
28
30
|
class << self
|
29
31
|
|
32
|
+
# :stopdoc:
|
33
|
+
|
34
|
+
##
|
35
|
+
# The transaction commit buffer. You shouldn't touch me.
|
36
|
+
|
37
|
+
attr_accessor :cache_delay_commit
|
38
|
+
|
30
39
|
##
|
31
40
|
# The local process cache. You shouldn't touch me.
|
32
41
|
|
33
42
|
attr_reader :cache_local
|
34
43
|
|
44
|
+
##
|
45
|
+
# The transaction nesting level. You shouldn't touch me.
|
46
|
+
|
47
|
+
attr_accessor :cache_transaction_level
|
48
|
+
|
49
|
+
# :startdoc:
|
50
|
+
|
35
51
|
##
|
36
52
|
# Enables or disables use of the local cache.
|
37
53
|
#
|
@@ -52,20 +68,6 @@ class CachedModel < ActiveRecord::Base
|
|
52
68
|
|
53
69
|
attr_accessor :ttl
|
54
70
|
|
55
|
-
##
|
56
|
-
# Returns true if use of the local cache is enabled.
|
57
|
-
|
58
|
-
def use_local_cache?
|
59
|
-
return @use_local_cache
|
60
|
-
end
|
61
|
-
|
62
|
-
##
|
63
|
-
# Returns true if use of memcache is enabled.
|
64
|
-
|
65
|
-
def use_memcache?
|
66
|
-
return @use_memcache
|
67
|
-
end
|
68
|
-
|
69
71
|
end
|
70
72
|
|
71
73
|
##
|
@@ -172,6 +174,37 @@ class CachedModel < ActiveRecord::Base
|
|
172
174
|
return records
|
173
175
|
end
|
174
176
|
|
177
|
+
##
|
178
|
+
# Delay updating the cache while in a transaction.
|
179
|
+
|
180
|
+
def self.transaction(*args)
|
181
|
+
level = CachedModel.cache_transaction_level += 1
|
182
|
+
CachedModel.cache_delay_commit[level] = []
|
183
|
+
|
184
|
+
value = super
|
185
|
+
|
186
|
+
waiting = CachedModel.cache_delay_commit.delete level
|
187
|
+
waiting.each do |obj| obj.cache_store end
|
188
|
+
|
189
|
+
return value
|
190
|
+
ensure
|
191
|
+
CachedModel.cache_transaction_level -= 1
|
192
|
+
end
|
193
|
+
|
194
|
+
##
|
195
|
+
# Returns true if use of the local cache is enabled.
|
196
|
+
|
197
|
+
def self.use_local_cache?
|
198
|
+
return @use_local_cache
|
199
|
+
end
|
200
|
+
|
201
|
+
##
|
202
|
+
# Returns true if use of memcache is enabled.
|
203
|
+
|
204
|
+
def self.use_memcache?
|
205
|
+
return @use_memcache
|
206
|
+
end
|
207
|
+
|
175
208
|
##
|
176
209
|
# Delete the entry from the cache now that it isn't in the DB.
|
177
210
|
|
@@ -236,12 +269,17 @@ class CachedModel < ActiveRecord::Base
|
|
236
269
|
def cache_store
|
237
270
|
obj = dup
|
238
271
|
obj.send :instance_variable_set, :@attributes, attributes_before_type_cast
|
239
|
-
if CachedModel.
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
272
|
+
if CachedModel.cache_delay_commit[CachedModel.cache_transaction_level].nil? then
|
273
|
+
if CachedModel.use_local_cache? then
|
274
|
+
cache_local[cache_key_local] = obj
|
275
|
+
end
|
276
|
+
if CachedModel.use_memcache? then
|
277
|
+
Cache.put cache_key_memcache, obj, CachedModel.ttl
|
278
|
+
end
|
279
|
+
else
|
280
|
+
CachedModel.cache_delay_commit[CachedModel.cache_transaction_level] << obj
|
244
281
|
end
|
282
|
+
nil
|
245
283
|
end
|
246
284
|
|
247
285
|
end
|
data/test/test_cached_model.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
require 'rubygems'
|
1
2
|
require 'test/unit'
|
3
|
+
require 'test/zentest_assertions'
|
2
4
|
|
3
5
|
$TESTING = true
|
4
6
|
$TESTING_CM = true
|
@@ -25,6 +27,7 @@ class ActiveRecord::Base
|
|
25
27
|
end
|
26
28
|
|
27
29
|
def self.abstract_class?
|
30
|
+
@abstract_class ||= false
|
28
31
|
return !!@abstract_class
|
29
32
|
end
|
30
33
|
|
@@ -68,6 +71,10 @@ class ActiveRecord::Base
|
|
68
71
|
name.downcase
|
69
72
|
end
|
70
73
|
|
74
|
+
def self.transaction(*a)
|
75
|
+
yield
|
76
|
+
end
|
77
|
+
|
71
78
|
def self.primary_key
|
72
79
|
'id'
|
73
80
|
end
|
@@ -95,6 +102,14 @@ class ActiveRecord::Base
|
|
95
102
|
@attributes[:extra] = nil
|
96
103
|
end
|
97
104
|
|
105
|
+
def save
|
106
|
+
update
|
107
|
+
end
|
108
|
+
|
109
|
+
def transaction(*a, &b)
|
110
|
+
self.class.transaction(*a, &b)
|
111
|
+
end
|
112
|
+
|
98
113
|
def update
|
99
114
|
end
|
100
115
|
|
@@ -133,6 +148,7 @@ end
|
|
133
148
|
class << CachedModel
|
134
149
|
|
135
150
|
attr_writer :cache_local
|
151
|
+
attr_writer :cache_delay_commit
|
136
152
|
|
137
153
|
end
|
138
154
|
|
@@ -145,6 +161,7 @@ class TestCachedModel < Test::Unit::TestCase
|
|
145
161
|
@model = Concrete.new
|
146
162
|
Cache.cache = {}
|
147
163
|
Cache.ttl = {}
|
164
|
+
CachedModel.cache_delay_commit = {}
|
148
165
|
CachedModel.cache_local = {}
|
149
166
|
CachedModel.use_local_cache = DEFAULT_USE_LOCAL_CACHE
|
150
167
|
CachedModel.use_memcache = DEFAULT_USE_MEMCACHE
|
@@ -167,8 +184,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
167
184
|
|
168
185
|
CachedModel.cache_delete @model.class, @model.id
|
169
186
|
|
170
|
-
|
171
|
-
|
187
|
+
assert_empty CachedModel.cache_local
|
188
|
+
assert_empty Cache.cache
|
172
189
|
end
|
173
190
|
|
174
191
|
def test_class_cache_delete_without_local_cache
|
@@ -178,8 +195,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
178
195
|
|
179
196
|
CachedModel.cache_delete @model.class, @model.id
|
180
197
|
|
181
|
-
|
182
|
-
|
198
|
+
deny_empty CachedModel.cache_local
|
199
|
+
assert_empty Cache.cache
|
183
200
|
end
|
184
201
|
|
185
202
|
def test_class_cache_delete_without_memcache
|
@@ -189,8 +206,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
189
206
|
|
190
207
|
CachedModel.cache_delete @model.class, @model.id
|
191
208
|
|
192
|
-
|
193
|
-
|
209
|
+
assert_empty CachedModel.cache_local
|
210
|
+
deny_empty Cache.cache
|
194
211
|
end
|
195
212
|
|
196
213
|
def test_class_cache_reset
|
@@ -200,8 +217,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
200
217
|
|
201
218
|
CachedModel.cache_reset
|
202
219
|
|
203
|
-
|
204
|
-
|
220
|
+
assert_empty CachedModel.cache_local
|
221
|
+
deny_empty Cache.cache
|
205
222
|
end
|
206
223
|
|
207
224
|
def test_class_cache_reset_without_local_cache
|
@@ -211,8 +228,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
211
228
|
|
212
229
|
CachedModel.cache_reset
|
213
230
|
|
214
|
-
|
215
|
-
|
231
|
+
deny_empty CachedModel.cache_local
|
232
|
+
deny_empty Cache.cache
|
216
233
|
end
|
217
234
|
|
218
235
|
def test_class_cache_reset_without_memcache
|
@@ -222,8 +239,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
222
239
|
|
223
240
|
CachedModel.cache_reset
|
224
241
|
|
225
|
-
|
226
|
-
|
242
|
+
assert_empty CachedModel.cache_local
|
243
|
+
deny_empty Cache.cache
|
227
244
|
end
|
228
245
|
|
229
246
|
def test_class_find_complex
|
@@ -234,8 +251,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
234
251
|
|
235
252
|
assert_equal @model.id + 1, record.id
|
236
253
|
|
237
|
-
assert_equal record,
|
238
|
-
assert_equal record,
|
254
|
+
assert_equal record, util_local(record)
|
255
|
+
assert_equal record, util_memcache(record)
|
239
256
|
end
|
240
257
|
|
241
258
|
def test_class_find_complex_without_local_cache
|
@@ -246,8 +263,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
246
263
|
|
247
264
|
assert_equal @model.id + 1, record.id
|
248
265
|
|
249
|
-
assert_equal nil,
|
250
|
-
assert_equal record,
|
266
|
+
assert_equal nil, util_local(record)
|
267
|
+
assert_equal record, util_memcache(record)
|
251
268
|
end
|
252
269
|
|
253
270
|
def test_class_find_complex_without_memcache
|
@@ -258,8 +275,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
258
275
|
|
259
276
|
assert_equal @model.id + 1, record.id
|
260
277
|
|
261
|
-
assert_equal record,
|
262
|
-
assert_equal nil,
|
278
|
+
assert_equal record, util_local(record)
|
279
|
+
assert_equal nil, util_memcache(record)
|
263
280
|
end
|
264
281
|
|
265
282
|
def test_class_find_in_local_cache
|
@@ -269,7 +286,7 @@ class TestCachedModel < Test::Unit::TestCase
|
|
269
286
|
record = Concrete.find(1, :order => 'lock_version')
|
270
287
|
assert_equal @model.id + 1, record.id
|
271
288
|
|
272
|
-
assert_equal record,
|
289
|
+
assert_equal record, util_local(record)
|
273
290
|
end
|
274
291
|
|
275
292
|
def test_class_find_in_memcache
|
@@ -282,7 +299,7 @@ class TestCachedModel < Test::Unit::TestCase
|
|
282
299
|
|
283
300
|
assert_equal @model, record
|
284
301
|
|
285
|
-
assert_equal record,
|
302
|
+
assert_equal record, util_local(record)
|
286
303
|
end
|
287
304
|
|
288
305
|
def test_class_find_multiple
|
@@ -302,8 +319,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
302
319
|
record = Concrete.find @model.id + 1
|
303
320
|
assert_equal @model.id + 1, record.id
|
304
321
|
|
305
|
-
assert_equal record,
|
306
|
-
assert_equal record,
|
322
|
+
assert_equal record, util_local(record)
|
323
|
+
assert_equal record, util_memcache(record)
|
307
324
|
end
|
308
325
|
|
309
326
|
def test_class_find_by_sql
|
@@ -312,8 +329,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
312
329
|
record = Concrete.find_by_sql(q).first
|
313
330
|
assert_equal @model.id + 1, record.id
|
314
331
|
|
315
|
-
assert_equal record,
|
316
|
-
assert_equal record,
|
332
|
+
assert_equal record, util_local(record)
|
333
|
+
assert_equal record, util_memcache(record)
|
317
334
|
end
|
318
335
|
|
319
336
|
def test_class_find_by_sql_extra_space
|
@@ -322,8 +339,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
322
339
|
record = Concrete.find_by_sql(q).first
|
323
340
|
assert_equal @model.id + 1, record.id
|
324
341
|
|
325
|
-
assert_equal record,
|
326
|
-
assert_equal record,
|
342
|
+
assert_equal record, util_local(record)
|
343
|
+
assert_equal record, util_memcache(record)
|
327
344
|
end
|
328
345
|
|
329
346
|
def test_class_find_by_sql_no_record
|
@@ -360,8 +377,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
360
377
|
|
361
378
|
@model.cache_delete
|
362
379
|
|
363
|
-
|
364
|
-
|
380
|
+
assert_empty CachedModel.cache_local
|
381
|
+
assert_empty Cache.cache
|
365
382
|
end
|
366
383
|
|
367
384
|
def test_cache_key_local
|
@@ -383,25 +400,37 @@ class TestCachedModel < Test::Unit::TestCase
|
|
383
400
|
|
384
401
|
@model.cache_store
|
385
402
|
|
386
|
-
|
387
|
-
|
403
|
+
deny_empty CachedModel.cache_local
|
404
|
+
deny_empty Cache.cache
|
388
405
|
|
389
|
-
assert_equal @model,
|
390
|
-
assert_equal @model,
|
406
|
+
assert_equal @model, util_local(@model)
|
407
|
+
assert_equal @model, util_memcache(@model)
|
391
408
|
assert_equal CachedModel.ttl, Cache.ttl[@model.cache_key_memcache]
|
392
409
|
end
|
393
410
|
|
411
|
+
def test_cache_store_in_transaction
|
412
|
+
CachedModel.use_local_cache = true
|
413
|
+
CachedModel.use_memcache = true
|
414
|
+
CachedModel.cache_delay_commit[0] = []
|
415
|
+
|
416
|
+
@model.cache_store
|
417
|
+
|
418
|
+
deny_empty CachedModel.cache_delay_commit
|
419
|
+
assert_empty CachedModel.cache_local
|
420
|
+
assert_empty Cache.cache
|
421
|
+
end
|
422
|
+
|
394
423
|
def test_cache_store_without_local_cache
|
395
424
|
CachedModel.use_local_cache = false
|
396
425
|
CachedModel.use_memcache = true
|
397
426
|
|
398
427
|
@model.cache_store
|
399
428
|
|
400
|
-
|
401
|
-
|
429
|
+
assert_empty CachedModel.cache_local
|
430
|
+
deny_empty Cache.cache
|
402
431
|
|
403
|
-
assert_equal nil,
|
404
|
-
assert_equal @model,
|
432
|
+
assert_equal nil, util_local(@model)
|
433
|
+
assert_equal @model, util_memcache(@model)
|
405
434
|
assert_equal CachedModel.ttl, Cache.ttl[@model.cache_key_memcache]
|
406
435
|
end
|
407
436
|
|
@@ -411,22 +440,23 @@ class TestCachedModel < Test::Unit::TestCase
|
|
411
440
|
|
412
441
|
@model.cache_store
|
413
442
|
|
414
|
-
|
415
|
-
|
443
|
+
deny_empty CachedModel.cache_local
|
444
|
+
assert_empty Cache.cache
|
416
445
|
|
417
|
-
assert_equal @model,
|
418
|
-
assert_equal nil,
|
446
|
+
assert_equal @model, util_local(@model)
|
447
|
+
assert_equal nil, util_memcache(@model)
|
419
448
|
end
|
420
449
|
|
421
450
|
def test_cache_store_with_attributes
|
422
451
|
CachedModel.use_local_cache = true
|
423
452
|
@model.attributes[:extra] = 'extra'
|
424
453
|
@model.cache_store
|
425
|
-
assert_equal false, CachedModel.cache_local.empty?
|
426
|
-
assert_equal false, Cache.cache.empty?
|
427
454
|
|
428
|
-
|
429
|
-
|
455
|
+
deny_empty CachedModel.cache_local
|
456
|
+
deny_empty Cache.cache
|
457
|
+
|
458
|
+
local_model = util_local(@model)
|
459
|
+
mem_model = util_memcache(@model)
|
430
460
|
assert_equal @model, local_model
|
431
461
|
assert_equal @model, mem_model
|
432
462
|
assert_equal CachedModel.ttl, Cache.ttl[@model.cache_key_memcache]
|
@@ -443,8 +473,8 @@ class TestCachedModel < Test::Unit::TestCase
|
|
443
473
|
|
444
474
|
@model.destroy
|
445
475
|
|
446
|
-
|
447
|
-
|
476
|
+
assert_empty CachedModel.cache_local
|
477
|
+
assert_empty Cache.cache
|
448
478
|
end
|
449
479
|
|
450
480
|
def test_reload
|
@@ -452,28 +482,105 @@ class TestCachedModel < Test::Unit::TestCase
|
|
452
482
|
|
453
483
|
@model.reload
|
454
484
|
|
455
|
-
|
456
|
-
|
485
|
+
deny_empty CachedModel.cache_local
|
486
|
+
deny_empty Cache.cache
|
457
487
|
|
458
488
|
assert_equal 'datb',
|
459
|
-
|
489
|
+
util_local(@model).attributes[:data]
|
460
490
|
assert_equal 'datb',
|
461
|
-
|
491
|
+
util_memcache(@model).attributes[:data]
|
492
|
+
end
|
493
|
+
|
494
|
+
def test_transaction_fail
|
495
|
+
CachedModel.use_local_cache = true
|
496
|
+
|
497
|
+
e = assert_raise RuntimeError do
|
498
|
+
@model.transaction do
|
499
|
+
@model.attributes[:data] = 'atad'
|
500
|
+
@model.save
|
501
|
+
raise 'Oh nos!'
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
assert_equal 'Oh nos!', e.message
|
506
|
+
assert_equal nil, util_local(@model)
|
507
|
+
assert_equal nil, util_memcache(@model)
|
508
|
+
end
|
509
|
+
|
510
|
+
def test_transaction_nested
|
511
|
+
CachedModel.use_local_cache = true
|
512
|
+
|
513
|
+
@model.transaction do
|
514
|
+
@model.transaction do
|
515
|
+
@model.attributes[:data] = 'value1'
|
516
|
+
@model.save
|
517
|
+
|
518
|
+
assert_equal nil, util_local(@model), 'in t1 local'
|
519
|
+
assert_equal nil, util_memcache(@model), 'in t1 memcache'
|
520
|
+
end
|
521
|
+
|
522
|
+
assert_equal 'value1', util_local(@model).attributes[:data],
|
523
|
+
'completed t1 local'
|
524
|
+
assert_equal 'value1', util_memcache(@model).attributes[:data],
|
525
|
+
'completed t1 memcache'
|
526
|
+
|
527
|
+
@model.attributes[:data] = 'value2'
|
528
|
+
@model.save
|
529
|
+
|
530
|
+
assert_equal 'value1', util_local(@model).attributes[:data],
|
531
|
+
'in t2 local'
|
532
|
+
assert_equal 'value1', util_memcache(@model).attributes[:data],
|
533
|
+
'in t2 memcache'
|
534
|
+
end
|
535
|
+
|
536
|
+
assert_equal 'value2', util_local(@model).attributes[:data],
|
537
|
+
'completed t2 local'
|
538
|
+
assert_equal 'value2', util_memcache(@model).attributes[:data],
|
539
|
+
'completed t2 local'
|
540
|
+
end
|
541
|
+
|
542
|
+
def test_transaction_pass
|
543
|
+
CachedModel.use_local_cache = true
|
544
|
+
|
545
|
+
result = @model.transaction do
|
546
|
+
@model.attributes[:data] = 'atad'
|
547
|
+
@model.save
|
548
|
+
|
549
|
+
assert_equal nil, util_local(@model)
|
550
|
+
assert_equal nil, util_memcache(@model)
|
551
|
+
|
552
|
+
:some_value
|
553
|
+
end
|
554
|
+
|
555
|
+
assert_equal :some_value, result
|
556
|
+
|
557
|
+
assert_equal 'atad', util_local(@model).attributes[:data]
|
558
|
+
assert_equal 'atad',
|
559
|
+
util_memcache(@model).attributes[:data]
|
560
|
+
|
462
561
|
end
|
463
562
|
|
464
563
|
def test_update
|
465
564
|
util_set
|
466
565
|
|
467
566
|
@model.attributes[:data] = 'atad'
|
468
|
-
@model.update
|
567
|
+
assert_equal true, @model.update, "Updates should return true"
|
469
568
|
|
470
|
-
|
471
|
-
|
569
|
+
deny_empty CachedModel.cache_local
|
570
|
+
deny_empty Cache.cache
|
472
571
|
|
473
572
|
assert_equal 'atad',
|
474
|
-
|
573
|
+
util_local(@model).attributes[:data]
|
475
574
|
assert_equal 'atad',
|
476
|
-
|
575
|
+
util_memcache(@model).attributes[:data]
|
576
|
+
end
|
577
|
+
|
578
|
+
def util_local(model)
|
579
|
+
CachedModel.cache_local[model.cache_key_local]
|
580
|
+
end
|
581
|
+
|
582
|
+
def util_memcache(model)
|
583
|
+
Cache.cache[model.cache_key_memcache]
|
477
584
|
end
|
478
585
|
|
479
586
|
def util_set(klass = @model.class, id = @model.id, data = @model)
|
metadata
CHANGED
@@ -3,15 +3,16 @@ rubygems_version: 0.8.99
|
|
3
3
|
specification_version: 1
|
4
4
|
name: cached_model
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.
|
7
|
-
date: 2006-
|
8
|
-
summary: An ActiveRecord
|
6
|
+
version: 1.3.1
|
7
|
+
date: 2006-10-23 00:00:00 -07:00
|
8
|
+
summary: An ActiveRecord abstract model that caches records in memcached
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
- test
|
12
|
+
email: eric@robotcoop.com
|
13
|
+
homepage: http://dev.robotcoop.com/Libraries/cached_model
|
14
|
+
rubyforge_project: rctools
|
15
|
+
description: CachedModel caches simple (by id) finds in memcached reducing the amount of work the database needs to perform for simple queries.
|
15
16
|
autorequire:
|
16
17
|
default_executable:
|
17
18
|
bindir: bin
|
@@ -27,11 +28,13 @@ signing_key:
|
|
27
28
|
cert_chain:
|
28
29
|
post_install_message:
|
29
30
|
authors:
|
30
|
-
-
|
31
|
+
- Eric Hodel
|
32
|
+
- Robert Cottrell
|
31
33
|
files:
|
32
|
-
-
|
34
|
+
- History.txt
|
35
|
+
- LICENSE.txt
|
33
36
|
- Manifest.txt
|
34
|
-
- README
|
37
|
+
- README.txt
|
35
38
|
- Rakefile
|
36
39
|
- lib/cached_model.rb
|
37
40
|
- test/test_cached_model.rb
|
@@ -48,6 +51,15 @@ extensions: []
|
|
48
51
|
requirements: []
|
49
52
|
|
50
53
|
dependencies:
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: hoe
|
56
|
+
version_requirement:
|
57
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.1.2
|
62
|
+
version:
|
51
63
|
- !ruby/object:Gem::Dependency
|
52
64
|
name: memcache-client
|
53
65
|
version_requirement:
|
@@ -55,5 +67,23 @@ dependencies:
|
|
55
67
|
requirements:
|
56
68
|
- - ">="
|
57
69
|
- !ruby/object:Gem::Version
|
58
|
-
version: 1.0
|
70
|
+
version: 1.1.0
|
71
|
+
version:
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: activerecord
|
74
|
+
version_requirement:
|
75
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 1.14.4
|
80
|
+
version:
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: ZenTest
|
83
|
+
version_requirement:
|
84
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 3.4.1
|
59
89
|
version:
|