record-cache 0.1.2 → 0.1.3
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 +15 -0
- data/lib/record_cache.rb +2 -1
- data/lib/record_cache/base.rb +63 -22
- data/lib/record_cache/datastore/active_record.rb +5 -3
- data/lib/record_cache/datastore/active_record_30.rb +95 -38
- data/lib/record_cache/datastore/active_record_31.rb +157 -54
- data/lib/record_cache/datastore/active_record_32.rb +444 -0
- data/lib/record_cache/dispatcher.rb +47 -47
- data/lib/record_cache/multi_read.rb +14 -1
- data/lib/record_cache/query.rb +36 -25
- data/lib/record_cache/statistics.rb +5 -5
- data/lib/record_cache/strategy/base.rb +49 -19
- data/lib/record_cache/strategy/full_table_cache.rb +81 -0
- data/lib/record_cache/strategy/index_cache.rb +38 -36
- data/lib/record_cache/strategy/unique_index_cache.rb +130 -0
- data/lib/record_cache/strategy/util.rb +12 -12
- data/lib/record_cache/test/resettable_version_store.rb +2 -9
- data/lib/record_cache/version.rb +1 -1
- data/lib/record_cache/version_store.rb +23 -16
- data/spec/db/schema.rb +12 -0
- data/spec/db/seeds.rb +10 -0
- data/spec/lib/active_record/visitor_spec.rb +22 -0
- data/spec/lib/base_spec.rb +21 -0
- data/spec/lib/dispatcher_spec.rb +24 -46
- data/spec/lib/multi_read_spec.rb +6 -6
- data/spec/lib/query_spec.rb +43 -43
- data/spec/lib/statistics_spec.rb +28 -28
- data/spec/lib/strategy/base_spec.rb +98 -87
- data/spec/lib/strategy/full_table_cache_spec.rb +68 -0
- data/spec/lib/strategy/index_cache_spec.rb +112 -69
- data/spec/lib/strategy/query_cache_spec.rb +83 -0
- data/spec/lib/strategy/unique_index_on_id_cache_spec.rb +317 -0
- data/spec/lib/strategy/unique_index_on_string_cache_spec.rb +168 -0
- data/spec/lib/strategy/util_spec.rb +67 -49
- data/spec/lib/version_store_spec.rb +22 -41
- data/spec/models/address.rb +9 -0
- data/spec/models/apple.rb +1 -1
- data/spec/models/banana.rb +21 -2
- data/spec/models/language.rb +5 -0
- data/spec/models/person.rb +1 -1
- data/spec/models/store.rb +2 -1
- data/spec/spec_helper.rb +7 -4
- data/spec/support/after_commit.rb +2 -0
- data/spec/support/matchers/hit_cache_matcher.rb +10 -6
- data/spec/support/matchers/log.rb +45 -0
- data/spec/support/matchers/miss_cache_matcher.rb +10 -6
- data/spec/support/matchers/use_cache_matcher.rb +10 -6
- metadata +156 -161
- data/lib/record_cache/strategy/id_cache.rb +0 -93
- data/lib/record_cache/strategy/request_cache.rb +0 -49
- data/spec/lib/strategy/id_cache_spec.rb +0 -168
- data/spec/lib/strategy/request_cache_spec.rb +0 -85
@@ -1,93 +0,0 @@
|
|
1
|
-
module RecordCache
|
2
|
-
module Strategy
|
3
|
-
class IdCache < Base
|
4
|
-
|
5
|
-
# Can the cache retrieve the records based on this query?
|
6
|
-
def cacheable?(query)
|
7
|
-
ids = query.where_ids(:id)
|
8
|
-
ids && (query.limit.nil? || (query.limit == 1 && ids.size == 1))
|
9
|
-
end
|
10
|
-
|
11
|
-
# Update the version store and the record store
|
12
|
-
def record_change(record, action)
|
13
|
-
key = cache_key(record.id)
|
14
|
-
if action == :destroy
|
15
|
-
version_store.delete(key)
|
16
|
-
else
|
17
|
-
# update the version store and add the record to the cache
|
18
|
-
new_version = version_store.increment(key)
|
19
|
-
record_store.write(versioned_key(key, new_version), Util.serialize(record))
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# Handle invalidation call
|
24
|
-
def invalidate(id)
|
25
|
-
version_store.delete(cache_key(id))
|
26
|
-
end
|
27
|
-
|
28
|
-
protected
|
29
|
-
|
30
|
-
# retrieve the record(s) with the given id(s) as an array
|
31
|
-
def fetch_records(query)
|
32
|
-
ids = query.where_ids(:id)
|
33
|
-
query.wheres.delete(:id) # make sure CacheCase.filter! does not see this where anymore
|
34
|
-
id_to_key_map = ids.inject({}){|h,id| h[id] = cache_key(id); h }
|
35
|
-
# retrieve the current version of the records
|
36
|
-
current_versions = version_store.current_multi(id_to_key_map)
|
37
|
-
# get the keys for the records for which a current version was found
|
38
|
-
id_to_version_key_map = Hash[id_to_key_map.map{ |id, key| current_versions[id] ? [id, versioned_key(key, current_versions[id])] : nil }]
|
39
|
-
# retrieve the records from the cache
|
40
|
-
records = id_to_version_key_map.size > 0 ? from_cache(id_to_version_key_map) : []
|
41
|
-
# query the records with missing ids
|
42
|
-
id_to_key_map.except!(*records.map(&:id))
|
43
|
-
# logging (only in debug mode!) and statistics
|
44
|
-
log_id_cache_hit(ids, id_to_key_map.keys) if RecordCache::Base.logger.debug?
|
45
|
-
statistics.add(ids.size, records.size) if statistics.active?
|
46
|
-
# retrieve records from DB in case there are some missing ids
|
47
|
-
records += from_db(id_to_key_map, id_to_version_key_map) if id_to_key_map.size > 0
|
48
|
-
# return the array
|
49
|
-
records
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
# ---------------------------- Querying ------------------------------------
|
55
|
-
|
56
|
-
# retrieve the records from the cache with the given keys
|
57
|
-
def from_cache(id_to_versioned_key_map)
|
58
|
-
records = record_store.read_multi(*(id_to_versioned_key_map.values)).values.compact
|
59
|
-
records.map{ |record| Util.deserialize(record) }
|
60
|
-
end
|
61
|
-
|
62
|
-
# retrieve the records with the given ids from the database
|
63
|
-
def from_db(id_to_key_map, id_to_version_key_map)
|
64
|
-
RecordCache::Base.without_record_cache do
|
65
|
-
# retrieve the records from the database
|
66
|
-
records = @base.where(:id => id_to_key_map.keys).to_a
|
67
|
-
records.each do |record|
|
68
|
-
versioned_key = id_to_version_key_map[record.id]
|
69
|
-
unless versioned_key
|
70
|
-
# renew the key in the version store in case it was missing
|
71
|
-
key = id_to_key_map[record.id]
|
72
|
-
versioned_key = versioned_key(key, version_store.renew(key))
|
73
|
-
end
|
74
|
-
# store the record based on the versioned key
|
75
|
-
record_store.write(versioned_key, Util.serialize(record))
|
76
|
-
end
|
77
|
-
records
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# ------------------------- Utility methods ----------------------------
|
82
|
-
|
83
|
-
# log cache hit/miss to debug log
|
84
|
-
def log_id_cache_hit(ids, missing_ids)
|
85
|
-
hit = missing_ids.empty? ? "hit" : ids.size == missing_ids.size ? "miss" : "partial hit"
|
86
|
-
missing = missing_ids.empty? || ids.size == missing_ids.size ? "" : ": missing #{missing_ids.inspect}"
|
87
|
-
msg = "IdCache #{hit} for ids #{ids.size == 1 ? ids.first : ids.inspect}#{missing}"
|
88
|
-
RecordCache::Base.logger.debug(msg)
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# Remembers the queries performed during a single Request.
|
2
|
-
# If the same query is requested again the result is provided straight from local memory.
|
3
|
-
#
|
4
|
-
# Records are invalidated per model-klass, when any record is created, updated or destroyed.
|
5
|
-
module RecordCache
|
6
|
-
module Strategy
|
7
|
-
|
8
|
-
class RequestCache < Base
|
9
|
-
@@request_store = {}
|
10
|
-
|
11
|
-
# call before each request: in application_controller.rb
|
12
|
-
# before_filter { |c| RecordCache::Strategy::RequestCache.clear }
|
13
|
-
def self.clear
|
14
|
-
@@request_store.clear
|
15
|
-
end
|
16
|
-
|
17
|
-
# Handle record change
|
18
|
-
def record_change(record, action)
|
19
|
-
@@request_store.delete(@base.name)
|
20
|
-
end
|
21
|
-
|
22
|
-
# Handle invalidation call
|
23
|
-
def invalidate(value)
|
24
|
-
@@request_store.delete(@base.name)
|
25
|
-
end
|
26
|
-
|
27
|
-
# return the records from the request cache, execute block in case
|
28
|
-
# this is the first time this query is performed during this request
|
29
|
-
def fetch(query, &block)
|
30
|
-
klass_store = (@@request_store[@base.name] ||= {})
|
31
|
-
key = query.cache_key
|
32
|
-
# logging (only in debug mode!) and statistics
|
33
|
-
log_cache_hit(key, klass_store.key?(key)) if RecordCache::Base.logger.debug?
|
34
|
-
statistics.add(1, klass_store.key?(key) ? 1 : 0) if statistics.active?
|
35
|
-
klass_store[key] ||= yield
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
# ------------------------- Utility methods ----------------------------
|
41
|
-
|
42
|
-
# log cache hit/miss to debug log
|
43
|
-
def log_cache_hit(key, hit)
|
44
|
-
RecordCache::Base.logger.debug("RequestCache #{hit ? 'hit' : 'miss'} for #{key}")
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,168 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RecordCache::Strategy::IdCache do
|
4
|
-
|
5
|
-
it "should retrieve an Apple from the cache" do
|
6
|
-
lambda{ Apple.find(1) }.should miss_cache(Apple).on(:id).times(1)
|
7
|
-
lambda{ Apple.find(1) }.should hit_cache(Apple).on(:id).times(1)
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should retrieve cloned records" do
|
11
|
-
@apple_1a = Apple.find(1)
|
12
|
-
@apple_1b = Apple.find(1)
|
13
|
-
@apple_1a.should == @apple_1b
|
14
|
-
@apple_1a.object_id.should_not == @apple_1b.object_id
|
15
|
-
end
|
16
|
-
|
17
|
-
context "logging" do
|
18
|
-
before(:each) do
|
19
|
-
Apple.find(1)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should write full hits to the debug log" do
|
23
|
-
mock(RecordCache::Base.logger).debug(/IdCache hit for ids 1|^(?!IdCache)/).times(any_times)
|
24
|
-
Apple.find(1)
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should write full miss to the debug log" do
|
28
|
-
mock(RecordCache::Base.logger).debug(/IdCache miss for ids 2|^(?!IdCache)/).times(any_times)
|
29
|
-
Apple.find(2)
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should write partial hits to the debug log" do
|
33
|
-
mock(RecordCache::Base.logger).debug(/IdCache partial hit for ids \[1, 2\]: missing \[2\]|^(?!IdCache)/).times(any_times)
|
34
|
-
Apple.where(:id => [1,2]).all
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context "cacheable?" do
|
39
|
-
before(:each) do
|
40
|
-
# fill cache
|
41
|
-
@apple1 = Apple.find(1)
|
42
|
-
@apple2 = Apple.find(2)
|
43
|
-
end
|
44
|
-
|
45
|
-
it "should use the cache when a single id is requested" do
|
46
|
-
lambda{ Apple.where(:id => 1).all }.should hit_cache(Apple).on(:id).times(1)
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should use the cache when a multiple ids are requested" do
|
50
|
-
lambda{ Apple.where(:id => [1, 2]).all }.should hit_cache(Apple).on(:id).times(2)
|
51
|
-
end
|
52
|
-
|
53
|
-
it "should use the cache when a single id is requested and the limit is 1" do
|
54
|
-
lambda{ Apple.where(:id => 1).limit(1).all }.should hit_cache(Apple).on(:id).times(1)
|
55
|
-
end
|
56
|
-
|
57
|
-
it "should not use the cache when a single id is requested and the limit is > 1" do
|
58
|
-
lambda{ Apple.where(:id => 1).limit(2).all }.should_not use_cache(Apple).on(:id)
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should not use the cache when multiple ids are requested and the limit is 1" do
|
62
|
-
lambda{ Apple.where(:id => [1, 2]).limit(1).all }.should_not use_cache(Apple).on(:id)
|
63
|
-
end
|
64
|
-
|
65
|
-
it "should use the cache when a single id is requested together with other where clauses" do
|
66
|
-
lambda{ Apple.where(:id => 1).where(:name => "Adams Apple x").all }.should hit_cache(Apple).on(:id).times(1)
|
67
|
-
end
|
68
|
-
|
69
|
-
it "should use the cache when a multiple ids are requested together with other where clauses" do
|
70
|
-
lambda{ Apple.where(:id => [1,2]).where(:name => "Adams Apple x").all }.should hit_cache(Apple).on(:id).times(2)
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should use the cache when a single id is requested together with (simple) sort clauses" do
|
74
|
-
lambda{ Apple.where(:id => 1).order("name ASC").all }.should hit_cache(Apple).on(:id).times(1)
|
75
|
-
end
|
76
|
-
|
77
|
-
it "should use the cache when a multiple ids are requested together with (simple) sort clauses" do
|
78
|
-
lambda{ Apple.where(:id => [1,2]).order("name ASC").all }.should hit_cache(Apple).on(:id).times(2)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
context "record_change" do
|
83
|
-
before(:each) do
|
84
|
-
# fill cache
|
85
|
-
@apple1 = Apple.find(1)
|
86
|
-
@apple2 = Apple.find(2)
|
87
|
-
end
|
88
|
-
|
89
|
-
it "should invalidate destroyed records" do
|
90
|
-
lambda{ Apple.where(:id => 1).all }.should hit_cache(Apple).on(:id).times(1)
|
91
|
-
@apple1.destroy
|
92
|
-
lambda{ @apples = Apple.where(:id => 1).all }.should miss_cache(Apple).on(:id).times(1)
|
93
|
-
@apples.should == []
|
94
|
-
# try again, to make sure the "missing record" is not cached
|
95
|
-
lambda{ Apple.where(:id => 1).all }.should miss_cache(Apple).on(:id).times(1)
|
96
|
-
end
|
97
|
-
|
98
|
-
it "should add updated records directly to the cache" do
|
99
|
-
@apple1.name = "Applejuice"
|
100
|
-
@apple1.save!
|
101
|
-
lambda{ @apple = Apple.find(1) }.should hit_cache(Apple).on(:id).times(1)
|
102
|
-
@apple.name.should == "Applejuice"
|
103
|
-
end
|
104
|
-
|
105
|
-
it "should add created records directly to the cache" do
|
106
|
-
@new_apple = Apple.create!(:name => "Fresh Apple", :store_id => 1)
|
107
|
-
lambda{ @apple = Apple.find(@new_apple.id) }.should hit_cache(Apple).on(:id).times(1)
|
108
|
-
@apple.name.should == "Fresh Apple"
|
109
|
-
end
|
110
|
-
|
111
|
-
it "should add updated records to the cache, also when multiple ids are queried" do
|
112
|
-
@apple1.name = "Applejuice"
|
113
|
-
@apple1.save!
|
114
|
-
lambda{ @apples = Apple.where(:id => [1, 2]).order('id ASC').all }.should hit_cache(Apple).on(:id).times(2)
|
115
|
-
@apples.map(&:name).should == ["Applejuice", "Adams Apple 2"]
|
116
|
-
end
|
117
|
-
|
118
|
-
end
|
119
|
-
|
120
|
-
context "invalidate" do
|
121
|
-
before(:each) do
|
122
|
-
@apple1 = Apple.find(1)
|
123
|
-
@apple2 = Apple.find(2)
|
124
|
-
end
|
125
|
-
|
126
|
-
it "should invalidate single records" do
|
127
|
-
Apple.record_cache[:id].invalidate(1)
|
128
|
-
lambda{ Apple.find(1) }.should miss_cache(Apple).on(:id).times(1)
|
129
|
-
end
|
130
|
-
|
131
|
-
it "should only miss the cache for the invalidated record when multiple ids are queried" do
|
132
|
-
# miss on 1
|
133
|
-
Apple.record_cache[:id].invalidate(1)
|
134
|
-
lambda{ Apple.where(:id => [1, 2]).all }.should miss_cache(Apple).on(:id).times(1)
|
135
|
-
# hit on 2
|
136
|
-
Apple.record_cache[:id].invalidate(1)
|
137
|
-
lambda{ Apple.where(:id => [1, 2]).all }.should hit_cache(Apple).on(:id).times(1)
|
138
|
-
# nothing invalidated, both hit
|
139
|
-
lambda{ Apple.where(:id => [1, 2]).all }.should hit_cache(Apple).on(:id).times(2)
|
140
|
-
end
|
141
|
-
|
142
|
-
it "should invalidate records when using update_all" do
|
143
|
-
Apple.where(:id => [3,4,5]).all # fill id cache on all Adam Store apples
|
144
|
-
lambda{ @apples = Apple.where(:id => [1, 2, 3, 4, 5]).order('id ASC').all }.should hit_cache(Apple).on(:id).times(5)
|
145
|
-
@apples.map(&:name).should == ["Adams Apple 1", "Adams Apple 2", "Adams Apple 3", "Adams Apple 4", "Adams Apple 5"]
|
146
|
-
# update 3 of the 5 apples in the Adam Store
|
147
|
-
Apple.where(:id => [1,2,3]).update_all(:name => "Uniform Apple")
|
148
|
-
lambda{ @apples = Apple.where(:id => [1, 2, 3, 4, 5]).order('id ASC').all }.should hit_cache(Apple).on(:id).times(2)
|
149
|
-
@apples.map(&:name).should == ["Uniform Apple", "Uniform Apple", "Uniform Apple", "Adams Apple 4", "Adams Apple 5"]
|
150
|
-
end
|
151
|
-
|
152
|
-
it "should invalidate reflection indexes when a has_many relation is updated" do
|
153
|
-
# assign different apples to store 2
|
154
|
-
lambda{ Apple.where(:store_id => 1).all }.should hit_cache(Apple).on(:id).times(2)
|
155
|
-
store2_apple_ids = Apple.where(:store_id => 2).map(&:id)
|
156
|
-
store1 = Store.find(1)
|
157
|
-
store1.apple_ids = store2_apple_ids
|
158
|
-
store1.save!
|
159
|
-
# the apples that used to belong to store 2 are now in store 1 (incremental update)
|
160
|
-
lambda{ @apple1 = Apple.find(store2_apple_ids.first) }.should hit_cache(Apple).on(:id).times(1)
|
161
|
-
@apple1.store_id.should == 1
|
162
|
-
# the apples that used to belong to store 1 are now homeless (cache invalidated)
|
163
|
-
lambda{ @homeless_apple = Apple.find(1) }.should miss_cache(Apple).on(:id).times(1)
|
164
|
-
@homeless_apple.store_id.should == nil
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RecordCache::Strategy::RequestCache do
|
4
|
-
|
5
|
-
it "should retrieve a record from the Request Cache" do
|
6
|
-
lambda{ Store.find(1) }.should miss_cache(Store)
|
7
|
-
lambda{ Store.find(1) }.should hit_cache(Store).on(:request_cache).times(1)
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should retrieve the same record when the same query is used" do
|
11
|
-
@store_1 = Store.find(1)
|
12
|
-
@store_2 = Store.find(1)
|
13
|
-
@store_1.should == @store_2
|
14
|
-
@store_1.object_id.should == @store_2.object_id
|
15
|
-
end
|
16
|
-
|
17
|
-
context "logging" do
|
18
|
-
before(:each) do
|
19
|
-
Store.find(1)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should write hit to the debug log" do
|
23
|
-
mock(RecordCache::Base.logger).debug(/RequestCache hit for id=1\.L1|^(?!RequestCache)/).times(any_times)
|
24
|
-
Store.find(1)
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should write miss to the debug log" do
|
28
|
-
mock(RecordCache::Base.logger).debug(/^RequestCache miss for id=2.L1|^(?!RequestCache)/).times(any_times)
|
29
|
-
Store.find(2)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
context "record_change" do
|
34
|
-
before(:each) do
|
35
|
-
# cache query in request cache
|
36
|
-
@store1 = Store.find(1)
|
37
|
-
@store2 = Store.find(2)
|
38
|
-
end
|
39
|
-
|
40
|
-
it "should remove all records from the cache for a specific model when one record is destroyed" do
|
41
|
-
lambda{ Store.find(1) }.should hit_cache(Store).on(:request_cache).times(1)
|
42
|
-
lambda{ Store.find(2) }.should hit_cache(Store).on(:request_cache).times(1)
|
43
|
-
@store1.destroy
|
44
|
-
lambda{ Store.find(2) }.should miss_cache(Store).on(:request_cache).times(1)
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should remove all records from the cache for a specific model when one record is updated" do
|
48
|
-
lambda{ Store.find(1) }.should hit_cache(Store).on(:request_cache).times(1)
|
49
|
-
lambda{ Store.find(2) }.should hit_cache(Store).on(:request_cache).times(1)
|
50
|
-
@store1.name = "Store E"
|
51
|
-
@store1.save!
|
52
|
-
lambda{ Store.find(1) }.should miss_cache(Store).on(:request_cache).times(1)
|
53
|
-
lambda{ Store.find(2) }.should miss_cache(Store).on(:request_cache).times(1)
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should remove all records from the cache for a specific model when one record is created" do
|
57
|
-
lambda{ Store.find(1) }.should hit_cache(Store).on(:request_cache).times(1)
|
58
|
-
lambda{ Store.find(2) }.should hit_cache(Store).on(:request_cache).times(1)
|
59
|
-
Store.create!(:name => "New Apple Store")
|
60
|
-
lambda{ Store.find(1) }.should miss_cache(Store).on(:request_cache).times(1)
|
61
|
-
lambda{ Store.find(2) }.should miss_cache(Store).on(:request_cache).times(1)
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
context "invalidate" do
|
67
|
-
before(:each) do
|
68
|
-
# cache query in request cache
|
69
|
-
@store1 = Store.find(1)
|
70
|
-
@store2 = Store.find(2)
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should remove all records from the cache when clear is explicitly called" do
|
74
|
-
lambda{ Store.find(1) }.should hit_cache(Store).on(:request_cache).times(1)
|
75
|
-
RecordCache::Strategy::RequestCache.clear
|
76
|
-
lambda{ Store.find(1) }.should miss_cache(Store).on(:request_cache).times(1)
|
77
|
-
end
|
78
|
-
|
79
|
-
it "should remove all records from the cache when invalidate is called" do
|
80
|
-
lambda{ Store.find(1) }.should hit_cache(Store).on(:request_cache).times(1)
|
81
|
-
Store.record_cache.invalidate(:request_cache, @store2)
|
82
|
-
lambda{ Store.find(1) }.should miss_cache(Store).on(:request_cache).times(1)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|