cached_model 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.
- data/README +49 -1
- data/Rakefile +1 -1
- data/lib/cached_model.rb +79 -25
- data/test/test_cached_model.rb +181 -20
- metadata +3 -2
data/README
CHANGED
@@ -4,12 +4,30 @@ Rubyforge Project:
|
|
4
4
|
|
5
5
|
http://rubyforge.org/projects/rctools/
|
6
6
|
|
7
|
+
Documentation:
|
8
|
+
|
9
|
+
http://dev.robotcoop.com/Libraries/cached_model/
|
10
|
+
|
7
11
|
== About
|
8
12
|
|
9
13
|
CachedModel stores Rails ActiveRecord objects in memcache allowing for very
|
10
14
|
fast retrievals. CachedModel uses the ActiveRecord::Locking to ensure that
|
11
15
|
you don't perform multiple updates.
|
12
16
|
|
17
|
+
== CachedModel Doesn't...
|
18
|
+
|
19
|
+
CachedModel is not magic.
|
20
|
+
|
21
|
+
CachedModel only accelerates simple finds for single rows.
|
22
|
+
|
23
|
+
CachedModel won't cache every query you run.
|
24
|
+
|
25
|
+
CachedModel isn't smart enough to determine the dependencies between your
|
26
|
+
queries so that it can accelerate more complicated queries. Without these
|
27
|
+
smarts you'll only end up with a broken application.
|
28
|
+
|
29
|
+
If you want to cache more complicated queries you need do it by hand.
|
30
|
+
|
13
31
|
== Using CachedModel
|
14
32
|
|
15
33
|
First, install the cached_model gem:
|
@@ -50,7 +68,7 @@ Then make Rails load the gem:
|
|
50
68
|
$ tail -n 4 config/environment.rb
|
51
69
|
# Include your application configuration below
|
52
70
|
|
53
|
-
|
71
|
+
require 'cached_model'
|
54
72
|
|
55
73
|
Then edit your ActiveRecord model to inherit from CachedModel instead of
|
56
74
|
ActiveRecord::Base:
|
@@ -64,3 +82,33 @@ ActiveRecord::Base:
|
|
64
82
|
belongs_to :point
|
65
83
|
belongs_to :route
|
66
84
|
|
85
|
+
== Extra Features
|
86
|
+
|
87
|
+
=== Local Cache
|
88
|
+
|
89
|
+
CachedModel also incorporates an in-process cache, but it is disabled by
|
90
|
+
default. In order to enable the in-process cache enable it in your
|
91
|
+
environment.rb:
|
92
|
+
|
93
|
+
CachedModel.use_local_cache = true
|
94
|
+
|
95
|
+
And add a after_filter that flushes the local cache:
|
96
|
+
|
97
|
+
class ApplicationController < ActionController::Base
|
98
|
+
|
99
|
+
after_filter { CachedModel.cache_reset }
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
IF YOU DO NOT ADD THE AFTER FILTER YOU WILL EXPERIENCE EXTREME PROCESS GROWTH.
|
104
|
+
|
105
|
+
=== Memcache
|
106
|
+
|
107
|
+
Memcache may be disabled and the TTL for objects stored in memcache may be
|
108
|
+
changed:
|
109
|
+
|
110
|
+
CachedModel.use_memcache = false
|
111
|
+
CachedModel.ttl = 86400
|
112
|
+
|
113
|
+
The default TTL for memcache objects is 900 seconds.
|
114
|
+
|
data/Rakefile
CHANGED
@@ -8,7 +8,7 @@ $VERBOSE = nil
|
|
8
8
|
|
9
9
|
spec = Gem::Specification.new do |s|
|
10
10
|
s.name = 'cached_model'
|
11
|
-
s.version = '1.0
|
11
|
+
s.version = '1.1.0'
|
12
12
|
s.summary = 'An ActiveRecord::Base model that caches records'
|
13
13
|
s.authors = 'Robert Cottrell, Eric Hodel'
|
14
14
|
s.email = 'bob@robotcoop.com'
|
data/lib/cached_model.rb
CHANGED
@@ -9,12 +9,53 @@ require 'memcache_util' unless $TESTING == :cached_model
|
|
9
9
|
|
10
10
|
class CachedModel < ActiveRecord::Base
|
11
11
|
|
12
|
-
KEY = 'active_record'
|
13
|
-
TTL = 60 * 15 # seconds
|
14
|
-
|
15
12
|
@cache_local = {}
|
13
|
+
@use_local_cache = false
|
14
|
+
@use_memcache = true
|
15
|
+
@ttl = 60 * 15
|
16
16
|
|
17
|
-
class << self
|
17
|
+
class << self
|
18
|
+
|
19
|
+
##
|
20
|
+
# The local process cache. You shouldn't touch me.
|
21
|
+
|
22
|
+
attr_reader :cache_local
|
23
|
+
|
24
|
+
##
|
25
|
+
# Enables or disables use of the local cache.
|
26
|
+
#
|
27
|
+
# NOTE if you enable this you must call #cache_reset or you will
|
28
|
+
# experience uncontrollable process growth!
|
29
|
+
#
|
30
|
+
# Defaults to false.
|
31
|
+
|
32
|
+
attr_writer :use_local_cache
|
33
|
+
|
34
|
+
##
|
35
|
+
# Enables or disables the use of memcache.
|
36
|
+
|
37
|
+
attr_writer :use_memcache
|
38
|
+
|
39
|
+
##
|
40
|
+
# Memcache record time-to-live for stored records.
|
41
|
+
|
42
|
+
attr_accessor :ttl
|
43
|
+
|
44
|
+
##
|
45
|
+
# Returns true if use of the local cache is enabled.
|
46
|
+
|
47
|
+
def use_local_cache?
|
48
|
+
return @use_local_cache
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Returns true if use of memcache is enabled.
|
53
|
+
|
54
|
+
def use_memcache?
|
55
|
+
return @use_memcache
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
18
59
|
|
19
60
|
##
|
20
61
|
# Override the flawed assumption ActiveRecord::Base makes about inheritance.
|
@@ -22,7 +63,7 @@ class CachedModel < ActiveRecord::Base
|
|
22
63
|
def self.descends_from_active_record?
|
23
64
|
superclass == CachedModel
|
24
65
|
end
|
25
|
-
|
66
|
+
|
26
67
|
##
|
27
68
|
# Override the flawed assumption ActiveRecord::Base makes about inheritance.
|
28
69
|
|
@@ -36,21 +77,21 @@ class CachedModel < ActiveRecord::Base
|
|
36
77
|
end
|
37
78
|
end
|
38
79
|
|
39
|
-
##
|
80
|
+
##
|
40
81
|
# Invalidate the cache entry for an record. The update method will
|
41
82
|
# automatically invalidate the cache when updates are made through
|
42
83
|
# ActiveRecord model record. However, several methods update tables with
|
43
84
|
# direct sql queries for effeciency. These methods should call this method
|
44
85
|
# to invalidate the cache after making those changes.
|
45
|
-
#
|
86
|
+
#
|
46
87
|
# NOTE - if a SQL query updates multiple rows with one query, there is
|
47
88
|
# currently no way to invalidate the affected entries unless the entire
|
48
89
|
# cache is dumped or until the TTL expires, so try not to do this.
|
49
90
|
|
50
91
|
def self.cache_delete(klass, id)
|
51
92
|
key = "#{klass}:#{id}"
|
52
|
-
CachedModel.cache_local.delete key
|
53
|
-
Cache.delete "
|
93
|
+
CachedModel.cache_local.delete key if CachedModel.use_local_cache?
|
94
|
+
Cache.delete "active_record:#{key}" if CachedModel.use_memcache?
|
54
95
|
end
|
55
96
|
|
56
97
|
##
|
@@ -58,7 +99,7 @@ class CachedModel < ActiveRecord::Base
|
|
58
99
|
# filter at the beginning of each request.
|
59
100
|
|
60
101
|
def self.cache_reset
|
61
|
-
CachedModel.cache_local.clear
|
102
|
+
CachedModel.cache_local.clear if CachedModel.use_local_cache?
|
62
103
|
end
|
63
104
|
|
64
105
|
##
|
@@ -73,12 +114,14 @@ class CachedModel < ActiveRecord::Base
|
|
73
114
|
if ($TESTING and $TESTING != :cached_model) or
|
74
115
|
args.length != 1 or not Fixnum === args.first then
|
75
116
|
records = super
|
117
|
+
# Rails requires two levels of indirection to look up a record
|
118
|
+
return records if args.first == :all and @skip_find_hack
|
76
119
|
return records if RAILS_ENV == 'test'
|
77
120
|
case records
|
78
121
|
when Array then
|
79
122
|
records.each { |r| r.cache_store }
|
80
123
|
when CachedModel then
|
81
|
-
records.cache_store
|
124
|
+
records.cache_store # Model.find 1 gets cached here
|
82
125
|
end
|
83
126
|
return records
|
84
127
|
end
|
@@ -86,26 +129,33 @@ class CachedModel < ActiveRecord::Base
|
|
86
129
|
# Try to find the record in the local cache.
|
87
130
|
id = args.first
|
88
131
|
cache_key_local = "#{name}:#{id}"
|
89
|
-
|
90
|
-
|
132
|
+
if CachedModel.use_local_cache? then
|
133
|
+
record = CachedModel.cache_local[cache_key_local]
|
134
|
+
return record unless record.nil?
|
135
|
+
end
|
91
136
|
|
92
137
|
# Try to find the record in memcache and add it to the local cache
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
138
|
+
if CachedModel.use_memcache? then
|
139
|
+
record = Cache.get "active_record:#{cache_key_local}"
|
140
|
+
unless record.nil? then
|
141
|
+
if CachedModel.use_local_cache? then
|
142
|
+
CachedModel.cache_local[cache_key_local] = record
|
143
|
+
end
|
144
|
+
return record
|
145
|
+
end
|
97
146
|
end
|
98
147
|
|
99
|
-
# Fetch the record from the DB
|
148
|
+
# Fetch the record from the DB. Inside the mulitple levels of indirection
|
149
|
+
# of find it will get cached.
|
100
150
|
#
|
101
151
|
# We don't want the subsequent find_by_sql to loop back here, so guard
|
102
152
|
# the call.
|
103
153
|
#
|
104
|
-
# NOTE
|
154
|
+
# NOTE This guard is not thread safe, beware use of CachedModel where
|
155
|
+
# ActiveRecord's thread safety is disabled.
|
105
156
|
begin
|
106
157
|
@skip_find_hack = true
|
107
158
|
record = super(args).first
|
108
|
-
record.cache_store
|
109
159
|
ensure
|
110
160
|
@skip_find_hack = false
|
111
161
|
end
|
@@ -160,8 +210,8 @@ class CachedModel < ActiveRecord::Base
|
|
160
210
|
# Remove this record from the cache.
|
161
211
|
|
162
212
|
def cache_delete
|
163
|
-
cache_local.delete cache_key_local
|
164
|
-
Cache.delete cache_key_memcache
|
213
|
+
cache_local.delete cache_key_local if CachedModel.use_local_cache?
|
214
|
+
Cache.delete cache_key_memcache if CachedModel.use_memcache?
|
165
215
|
end
|
166
216
|
|
167
217
|
##
|
@@ -175,7 +225,7 @@ class CachedModel < ActiveRecord::Base
|
|
175
225
|
# The memcache key for this record.
|
176
226
|
|
177
227
|
def cache_key_memcache
|
178
|
-
return "
|
228
|
+
return "active_record:#{cache_key_local}"
|
179
229
|
end
|
180
230
|
|
181
231
|
##
|
@@ -192,8 +242,12 @@ class CachedModel < ActiveRecord::Base
|
|
192
242
|
def cache_store
|
193
243
|
obj = dup
|
194
244
|
obj.send :instance_variable_set, :@attributes, attributes_before_type_cast
|
195
|
-
|
196
|
-
|
245
|
+
if CachedModel.use_local_cache? then
|
246
|
+
cache_local[cache_key_local] = obj
|
247
|
+
end
|
248
|
+
if CachedModel.use_memcache? then
|
249
|
+
Cache.put cache_key_memcache, obj, CachedModel.ttl
|
250
|
+
end
|
197
251
|
end
|
198
252
|
|
199
253
|
end
|
data/test/test_cached_model.rb
CHANGED
@@ -12,6 +12,32 @@ class ActiveRecord::Base
|
|
12
12
|
|
13
13
|
attr_accessor :id, :attributes
|
14
14
|
|
15
|
+
def self.find(*args)
|
16
|
+
args.flatten!
|
17
|
+
case args.first
|
18
|
+
when :first then
|
19
|
+
return find(:all, *args)
|
20
|
+
when :all then
|
21
|
+
[new]
|
22
|
+
else
|
23
|
+
case args.length
|
24
|
+
when 1 then
|
25
|
+
return find(:first, *args) if Fixnum === args.first
|
26
|
+
raise "Dunno what to do"
|
27
|
+
when 2 then
|
28
|
+
return new
|
29
|
+
when 3 then
|
30
|
+
return [new, new, new]
|
31
|
+
else
|
32
|
+
raise "Dunno what to do"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.find_by_sql(query)
|
38
|
+
return [new]
|
39
|
+
end
|
40
|
+
|
15
41
|
def self.next_id
|
16
42
|
@count += 1
|
17
43
|
return @count
|
@@ -25,17 +51,6 @@ class ActiveRecord::Base
|
|
25
51
|
'id'
|
26
52
|
end
|
27
53
|
|
28
|
-
def self.find(*args)
|
29
|
-
args.flatten!
|
30
|
-
return [new] if args.length == 1 and Fixnum === args.first
|
31
|
-
return new if args.length == 2
|
32
|
-
return [new, new, new] if args.length == 3
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.find_by_sql(query)
|
36
|
-
return [new]
|
37
|
-
end
|
38
|
-
|
39
54
|
def initialize
|
40
55
|
@id = ActiveRecord::Base.next_id
|
41
56
|
@attributes = { :data => 'data' }
|
@@ -102,14 +117,26 @@ end
|
|
102
117
|
|
103
118
|
class TestCachedModel < Test::Unit::TestCase
|
104
119
|
|
120
|
+
DEFAULT_USE_LOCAL_CACHE = CachedModel.use_local_cache?
|
121
|
+
DEFAULT_USE_MEMCACHE = CachedModel.use_memcache?
|
122
|
+
|
105
123
|
def setup
|
106
124
|
@model = Concrete.new
|
107
125
|
Cache.cache = {}
|
108
126
|
Cache.ttl = {}
|
109
127
|
CachedModel.cache_local = {}
|
128
|
+
CachedModel.use_local_cache = DEFAULT_USE_LOCAL_CACHE
|
129
|
+
CachedModel.use_memcache = DEFAULT_USE_MEMCACHE
|
130
|
+
end
|
131
|
+
|
132
|
+
def teardown
|
133
|
+
CachedModel.use_local_cache = DEFAULT_USE_LOCAL_CACHE
|
134
|
+
CachedModel.use_memcache = DEFAULT_USE_MEMCACHE
|
110
135
|
end
|
111
136
|
|
112
137
|
def test_class_cache_delete
|
138
|
+
CachedModel.use_local_cache = true
|
139
|
+
CachedModel.use_memcache = true
|
113
140
|
util_set
|
114
141
|
|
115
142
|
CachedModel.cache_delete @model.class, @model.id
|
@@ -118,7 +145,53 @@ class TestCachedModel < Test::Unit::TestCase
|
|
118
145
|
assert_equal true, Cache.cache.empty?
|
119
146
|
end
|
120
147
|
|
148
|
+
def test_class_cache_delete_without_local_cache
|
149
|
+
CachedModel.use_local_cache = false
|
150
|
+
CachedModel.use_memcache = true
|
151
|
+
util_set
|
152
|
+
|
153
|
+
CachedModel.cache_delete @model.class, @model.id
|
154
|
+
|
155
|
+
assert_equal false, CachedModel.cache_local.empty?
|
156
|
+
assert_equal true, Cache.cache.empty?
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_class_cache_delete_without_memcache
|
160
|
+
CachedModel.use_local_cache = true
|
161
|
+
CachedModel.use_memcache = false
|
162
|
+
util_set
|
163
|
+
|
164
|
+
CachedModel.cache_delete @model.class, @model.id
|
165
|
+
|
166
|
+
assert_equal true, CachedModel.cache_local.empty?
|
167
|
+
assert_equal false, Cache.cache.empty?
|
168
|
+
end
|
169
|
+
|
121
170
|
def test_class_cache_reset
|
171
|
+
CachedModel.use_local_cache = true
|
172
|
+
CachedModel.use_memcache = true
|
173
|
+
util_set
|
174
|
+
|
175
|
+
CachedModel.cache_reset
|
176
|
+
|
177
|
+
assert_equal true, CachedModel.cache_local.empty?
|
178
|
+
assert_equal false, Cache.cache.empty?
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_class_cache_reset_without_local_cache
|
182
|
+
CachedModel.use_local_cache = false
|
183
|
+
CachedModel.use_memcache = true
|
184
|
+
util_set
|
185
|
+
|
186
|
+
CachedModel.cache_reset
|
187
|
+
|
188
|
+
assert_equal false, CachedModel.cache_local.empty?
|
189
|
+
assert_equal false, Cache.cache.empty?
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_class_cache_reset_without_memcache
|
193
|
+
CachedModel.use_local_cache = true
|
194
|
+
CachedModel.use_memcache = false
|
122
195
|
util_set
|
123
196
|
|
124
197
|
CachedModel.cache_reset
|
@@ -133,45 +206,78 @@ class TestCachedModel < Test::Unit::TestCase
|
|
133
206
|
end
|
134
207
|
|
135
208
|
def test_class_find_complex
|
209
|
+
CachedModel.use_local_cache = true
|
210
|
+
CachedModel.use_memcache = true
|
211
|
+
|
136
212
|
record = Concrete.find(1, :order => 'lock_version')
|
213
|
+
|
137
214
|
assert_equal @model.id + 1, record.id
|
138
215
|
|
139
216
|
assert_equal record, CachedModel.cache_local[record.cache_key_local]
|
140
217
|
assert_equal record, Cache.cache[record.cache_key_memcache]
|
141
218
|
end
|
142
219
|
|
220
|
+
def test_class_find_complex_without_local_cache
|
221
|
+
CachedModel.use_local_cache = false
|
222
|
+
CachedModel.use_memcache = true
|
223
|
+
|
224
|
+
record = Concrete.find(1, :order => 'lock_version')
|
225
|
+
|
226
|
+
assert_equal @model.id + 1, record.id
|
227
|
+
|
228
|
+
assert_equal nil, CachedModel.cache_local[record.cache_key_local]
|
229
|
+
assert_equal record, Cache.cache[record.cache_key_memcache]
|
230
|
+
end
|
231
|
+
|
232
|
+
def test_class_find_complex_without_memcache
|
233
|
+
CachedModel.use_local_cache = true
|
234
|
+
CachedModel.use_memcache = false
|
235
|
+
|
236
|
+
record = Concrete.find(1, :order => 'lock_version')
|
237
|
+
|
238
|
+
assert_equal @model.id + 1, record.id
|
239
|
+
|
240
|
+
assert_equal record, CachedModel.cache_local[record.cache_key_local]
|
241
|
+
assert_equal nil, Cache.cache[record.cache_key_memcache]
|
242
|
+
end
|
243
|
+
|
143
244
|
def test_class_find_in_local_cache
|
245
|
+
CachedModel.use_local_cache = true
|
144
246
|
util_set
|
145
247
|
|
146
248
|
record = Concrete.find(1, :order => 'lock_version')
|
147
249
|
assert_equal @model.id + 1, record.id
|
148
250
|
|
149
251
|
assert_equal record, CachedModel.cache_local[record.cache_key_local]
|
150
|
-
assert_equal record, Cache.cache[record.cache_key_memcache]
|
151
252
|
end
|
152
253
|
|
153
254
|
def test_class_find_in_memcache
|
255
|
+
CachedModel.use_local_cache = true
|
256
|
+
CachedModel.use_memcache = true
|
154
257
|
util_set
|
155
258
|
CachedModel.cache_reset
|
156
259
|
|
157
260
|
record = Concrete.find @model.id
|
261
|
+
|
158
262
|
assert_equal @model, record
|
159
263
|
|
160
264
|
assert_equal record, CachedModel.cache_local[record.cache_key_local]
|
161
265
|
end
|
162
266
|
|
163
267
|
def test_class_find_multiple
|
268
|
+
CachedModel.use_local_cache = true
|
164
269
|
ids = [@model.id + 1, @model.id + 2, @model.id + 3]
|
165
270
|
records = Concrete.find(*ids)
|
166
271
|
assert_equal ids, records.map { |r| r.id }
|
167
272
|
|
168
|
-
assert_equal ids.map { |i| "#{@model.class}:#{i}" },
|
169
|
-
CachedModel.cache_local.keys
|
170
|
-
assert_equal ids.map { |i| "
|
171
|
-
Cache.cache.keys
|
273
|
+
assert_equal ids.map { |i| "#{@model.class}:#{i}" }.sort,
|
274
|
+
CachedModel.cache_local.keys.sort
|
275
|
+
assert_equal ids.map { |i| "active_record:#{@model.class}:#{i}" }.sort,
|
276
|
+
Cache.cache.keys.sort
|
172
277
|
end
|
173
278
|
|
174
279
|
def test_class_find_not_cached
|
280
|
+
CachedModel.use_local_cache = true
|
175
281
|
record = Concrete.find @model.id + 1
|
176
282
|
assert_equal @model.id + 1, record.id
|
177
283
|
|
@@ -180,6 +286,7 @@ class TestCachedModel < Test::Unit::TestCase
|
|
180
286
|
end
|
181
287
|
|
182
288
|
def test_class_find_by_sql
|
289
|
+
CachedModel.use_local_cache = true
|
183
290
|
q = "SELECT * FROM concrete WHERE (concrete.id = #{@model.id + 1}) LIMIT 1"
|
184
291
|
record = Concrete.find_by_sql(q).first
|
185
292
|
assert_equal @model.id + 1, record.id
|
@@ -207,7 +314,28 @@ class TestCachedModel < Test::Unit::TestCase
|
|
207
314
|
CachedModel.class_name_of_active_record_descendant(STILameness)
|
208
315
|
end
|
209
316
|
|
317
|
+
def test_class_ttl
|
318
|
+
assert_equal 900, CachedModel.ttl
|
319
|
+
CachedModel.ttl = 800
|
320
|
+
assert_equal 800, CachedModel.ttl
|
321
|
+
end
|
322
|
+
|
323
|
+
def test_class_use_local_cache_eh
|
324
|
+
CachedModel.use_local_cache = true
|
325
|
+
assert_equal true, CachedModel.use_local_cache?
|
326
|
+
CachedModel.use_local_cache = false
|
327
|
+
assert_equal false, CachedModel.use_local_cache?
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_class_use_memcache_eh
|
331
|
+
CachedModel.use_memcache = true
|
332
|
+
assert_equal true, CachedModel.use_memcache?
|
333
|
+
CachedModel.use_memcache = false
|
334
|
+
assert_equal false, CachedModel.use_memcache?
|
335
|
+
end
|
336
|
+
|
210
337
|
def test_cache_delete
|
338
|
+
CachedModel.use_local_cache = true
|
211
339
|
util_set
|
212
340
|
|
213
341
|
@model.cache_delete
|
@@ -221,7 +349,7 @@ class TestCachedModel < Test::Unit::TestCase
|
|
221
349
|
end
|
222
350
|
|
223
351
|
def test_cache_key_memcache
|
224
|
-
assert_equal "
|
352
|
+
assert_equal "active_record:#{@model.class}:#{@model.id}",
|
225
353
|
@model.cache_key_memcache
|
226
354
|
end
|
227
355
|
|
@@ -230,16 +358,48 @@ class TestCachedModel < Test::Unit::TestCase
|
|
230
358
|
end
|
231
359
|
|
232
360
|
def test_cache_store
|
361
|
+
CachedModel.use_local_cache = true
|
362
|
+
CachedModel.use_memcache = true
|
363
|
+
|
233
364
|
@model.cache_store
|
365
|
+
|
234
366
|
assert_equal false, CachedModel.cache_local.empty?
|
235
367
|
assert_equal false, Cache.cache.empty?
|
236
368
|
|
237
369
|
assert_equal @model, CachedModel.cache_local[@model.cache_key_local]
|
238
370
|
assert_equal @model, Cache.cache[@model.cache_key_memcache]
|
239
|
-
assert_equal CachedModel
|
371
|
+
assert_equal CachedModel.ttl, Cache.ttl[@model.cache_key_memcache]
|
372
|
+
end
|
373
|
+
|
374
|
+
def test_cache_store_without_local_cache
|
375
|
+
CachedModel.use_local_cache = false
|
376
|
+
CachedModel.use_memcache = true
|
377
|
+
|
378
|
+
@model.cache_store
|
379
|
+
|
380
|
+
assert_equal true, CachedModel.cache_local.empty?
|
381
|
+
assert_equal false, Cache.cache.empty?
|
382
|
+
|
383
|
+
assert_equal nil, CachedModel.cache_local[@model.cache_key_local]
|
384
|
+
assert_equal @model, Cache.cache[@model.cache_key_memcache]
|
385
|
+
assert_equal CachedModel.ttl, Cache.ttl[@model.cache_key_memcache]
|
386
|
+
end
|
387
|
+
|
388
|
+
def test_cache_store_without_memcache
|
389
|
+
CachedModel.use_local_cache = true
|
390
|
+
CachedModel.use_memcache = false
|
391
|
+
|
392
|
+
@model.cache_store
|
393
|
+
|
394
|
+
assert_equal false, CachedModel.cache_local.empty?
|
395
|
+
assert_equal true, Cache.cache.empty?
|
396
|
+
|
397
|
+
assert_equal @model, CachedModel.cache_local[@model.cache_key_local]
|
398
|
+
assert_equal nil, Cache.cache[@model.cache_key_memcache]
|
240
399
|
end
|
241
400
|
|
242
401
|
def test_cache_store_with_attributes
|
402
|
+
CachedModel.use_local_cache = true
|
243
403
|
@model.attributes[:extra] = 'extra'
|
244
404
|
@model.cache_store
|
245
405
|
assert_equal false, CachedModel.cache_local.empty?
|
@@ -249,7 +409,7 @@ class TestCachedModel < Test::Unit::TestCase
|
|
249
409
|
mem_model = Cache.cache[@model.cache_key_memcache]
|
250
410
|
assert_equal @model, local_model
|
251
411
|
assert_equal @model, mem_model
|
252
|
-
assert_equal CachedModel
|
412
|
+
assert_equal CachedModel.ttl, Cache.ttl[@model.cache_key_memcache]
|
253
413
|
|
254
414
|
expected = {:data => 'data'}
|
255
415
|
|
@@ -258,6 +418,7 @@ class TestCachedModel < Test::Unit::TestCase
|
|
258
418
|
end
|
259
419
|
|
260
420
|
def test_destroy
|
421
|
+
CachedModel.use_local_cache = true
|
261
422
|
util_set
|
262
423
|
|
263
424
|
@model.destroy
|
@@ -298,7 +459,7 @@ class TestCachedModel < Test::Unit::TestCase
|
|
298
459
|
def util_set(klass = @model.class, id = @model.id, data = @model)
|
299
460
|
key = "#{klass}:#{id}"
|
300
461
|
CachedModel.cache_local[key] = data
|
301
|
-
Cache.cache["
|
462
|
+
Cache.cache["active_record:#{key}"] = data
|
302
463
|
end
|
303
464
|
|
304
465
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11.6
|
|
3
3
|
specification_version: 1
|
4
4
|
name: cached_model
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.0
|
7
|
-
date: 2006-
|
6
|
+
version: 1.1.0
|
7
|
+
date: 2006-02-19 00:00:00 -08:00
|
8
8
|
summary: An ActiveRecord::Base model that caches records
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -25,6 +25,7 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
25
25
|
platform: ruby
|
26
26
|
signing_key:
|
27
27
|
cert_chain:
|
28
|
+
post_install_message:
|
28
29
|
authors:
|
29
30
|
- Robert Cottrell, Eric Hodel
|
30
31
|
files:
|