nkallen-cache-money 0.2.4 → 0.2.5
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/TODO +0 -2
- data/lib/cash/accessor.rb +8 -7
- data/lib/cash/config.rb +12 -5
- data/lib/cash/finders.rb +5 -7
- data/spec/cash/accessor_spec.rb +30 -4
- data/spec/cash/finders_spec.rb +12 -0
- metadata +12 -3
data/TODO
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
TOP PRIORITY
|
2
2
|
|
3
3
|
REFACTOR
|
4
|
-
* Reorganize transactional spec
|
5
4
|
* Clarify terminology around cache/key/index, etc.
|
6
5
|
|
7
6
|
INFRASTRUCTURE
|
8
7
|
|
9
8
|
NEW FEATURES
|
10
9
|
* transactional get multi isn't really multi
|
11
|
-
* add on "not stored" should yield
|
12
10
|
|
13
11
|
BUGS
|
14
12
|
* Handle append strategy (using add rather than set?) to avoid race condition
|
data/lib/cash/accessor.rb
CHANGED
@@ -38,7 +38,9 @@ module Cash
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def add(key, value, options = {})
|
41
|
-
repository.add(cache_key(key), value, options[:ttl] || 0, options[:raw])
|
41
|
+
if repository.add(cache_key(key), value, options[:ttl] || 0, options[:raw]) == "NOT_STORED\r\n"
|
42
|
+
yield
|
43
|
+
end
|
42
44
|
end
|
43
45
|
|
44
46
|
def set(key, value, options = {})
|
@@ -46,15 +48,15 @@ module Cash
|
|
46
48
|
end
|
47
49
|
|
48
50
|
def incr(key, delta = 1, ttl = 0)
|
49
|
-
repository.incr(cache_key(key), delta) || begin
|
50
|
-
repository.add(cache_key
|
51
|
+
repository.incr(cache_key = cache_key(key), delta) || begin
|
52
|
+
repository.add(cache_key, (result = yield).to_s, ttl, true) { repository.incr(cache_key) }
|
51
53
|
result
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
55
57
|
def decr(key, delta = 1, ttl = 0)
|
56
|
-
repository.decr(cache_key(key), delta) || begin
|
57
|
-
repository.add(cache_key
|
58
|
+
repository.decr(cache_key = cache_key(key), delta) || begin
|
59
|
+
repository.add(cache_key, (result = yield).to_s, ttl, true) { repository.decr(cache_key) }
|
58
60
|
result
|
59
61
|
end
|
60
62
|
end
|
@@ -64,7 +66,7 @@ module Cash
|
|
64
66
|
end
|
65
67
|
|
66
68
|
def cache_key(key)
|
67
|
-
"#{name}/#{key.to_s.gsub(' ', '+')}"
|
69
|
+
"#{name}:#{cache_config.version}/#{key.to_s.gsub(' ', '+')}"
|
68
70
|
end
|
69
71
|
end
|
70
72
|
|
@@ -72,7 +74,6 @@ module Cash
|
|
72
74
|
def expire
|
73
75
|
self.class.expire(id)
|
74
76
|
end
|
75
|
-
alias_method :expire_cache, :expire
|
76
77
|
end
|
77
78
|
end
|
78
79
|
end
|
data/lib/cash/config.rb
CHANGED
@@ -9,11 +9,10 @@ module Cash
|
|
9
9
|
|
10
10
|
module ClassMethods
|
11
11
|
def self.extended(a_class)
|
12
|
-
a_class
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
12
|
+
class << a_class
|
13
|
+
attr_reader :cache_config
|
14
|
+
delegate :repository, :indices, :to => :@cache_config
|
15
|
+
alias_method_chain :inherited, :cache_config
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
@@ -27,6 +26,10 @@ module Cash
|
|
27
26
|
(@cache_config.indices.unshift(Index.new(@cache_config, self, attributes, options))).uniq!
|
28
27
|
end
|
29
28
|
|
29
|
+
def version(number)
|
30
|
+
@cache_config.options[:version] = number
|
31
|
+
end
|
32
|
+
|
30
33
|
def cache_config=(config)
|
31
34
|
@cache_config = config
|
32
35
|
end
|
@@ -52,6 +55,10 @@ module Cash
|
|
52
55
|
@options[:ttl]
|
53
56
|
end
|
54
57
|
|
58
|
+
def version
|
59
|
+
@options[:version] || 1
|
60
|
+
end
|
61
|
+
|
55
62
|
def indices
|
56
63
|
@indices ||= active_record == ActiveRecord::Base ? [] : [Index.new(self, active_record, active_record.primary_key)]
|
57
64
|
end
|
data/lib/cash/finders.rb
CHANGED
@@ -8,17 +8,15 @@ module Cash
|
|
8
8
|
|
9
9
|
module ClassMethods
|
10
10
|
def self.extended(active_record_class)
|
11
|
-
active_record_class
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
alias_method_chain :calculate, :cache
|
16
|
-
end
|
11
|
+
class << active_record_class
|
12
|
+
alias_method_chain :find_every, :cache
|
13
|
+
alias_method_chain :find_from_ids, :cache
|
14
|
+
alias_method_chain :calculate, :cache
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
20
18
|
def without_cache(&block)
|
21
|
-
|
19
|
+
with_scope(:find => {:readonly => true}, &block)
|
22
20
|
end
|
23
21
|
|
24
22
|
# User.find(:first, ...), User.find_by_foo(...), User.find(:all, ...), User.find_all_by_foo(...)
|
data/spec/cash/accessor_spec.rb
CHANGED
@@ -22,8 +22,8 @@ module Cash
|
|
22
22
|
describe 'when there is a total cache miss' do
|
23
23
|
it 'yields the keys to the block' do
|
24
24
|
Story.fetch(["yabba", "dabba"]) { |*missing_ids| ["doo", "doo"] }.should == {
|
25
|
-
"Story/yabba" => "doo",
|
26
|
-
"Story/dabba" => "doo"
|
25
|
+
"Story:1/yabba" => "doo",
|
26
|
+
"Story:1/dabba" => "doo"
|
27
27
|
}
|
28
28
|
end
|
29
29
|
end
|
@@ -32,8 +32,8 @@ module Cash
|
|
32
32
|
it 'yields just the missing ids to the block' do
|
33
33
|
Story.set("yabba", "dabba")
|
34
34
|
Story.fetch(["yabba", "dabba"]) { |*missing_ids| "doo" }.should == {
|
35
|
-
"Story/yabba" => "dabba",
|
36
|
-
"Story/dabba" => "doo"
|
35
|
+
"Story:1/yabba" => "dabba",
|
36
|
+
"Story:1/dabba" => "doo"
|
37
37
|
}
|
38
38
|
end
|
39
39
|
end
|
@@ -102,6 +102,22 @@ module Cash
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
+
describe '#add' do
|
106
|
+
describe 'when the value already exists' do
|
107
|
+
it 'yields to the block' do
|
108
|
+
Story.set("count", 1)
|
109
|
+
Story.add("count", 1) { "yield me" }.should == "yield me"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe 'when the value does not already exist' do
|
114
|
+
it 'adds the key to the cache' do
|
115
|
+
Story.add("count", 1)
|
116
|
+
Story.get("count").should == 1
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
105
121
|
describe '#decr' do
|
106
122
|
describe 'when there is a cache hit' do
|
107
123
|
before do
|
@@ -129,5 +145,15 @@ module Cash
|
|
129
145
|
end
|
130
146
|
end
|
131
147
|
end
|
148
|
+
|
149
|
+
describe '#cache_key' do
|
150
|
+
it 'uses the version number' do
|
151
|
+
Story.version 1
|
152
|
+
Story.cache_key("foo").should == "Story:1/foo"
|
153
|
+
|
154
|
+
Story.version 2
|
155
|
+
Story.cache_key("foo").should == "Story:2/foo"
|
156
|
+
end
|
157
|
+
end
|
132
158
|
end
|
133
159
|
end
|
data/spec/cash/finders_spec.rb
CHANGED
@@ -294,6 +294,18 @@ module Cash
|
|
294
294
|
end
|
295
295
|
end
|
296
296
|
end
|
297
|
+
|
298
|
+
describe '#without_cache' do
|
299
|
+
describe 'when finders are called within the provided block' do
|
300
|
+
it 'uses the database not the cache' do
|
301
|
+
story = Story.create!
|
302
|
+
mock(Story).get.never
|
303
|
+
Story.without_cache do
|
304
|
+
Story.find(story.id).should == story
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
297
309
|
end
|
298
310
|
|
299
311
|
describe 'when the cache is not populated' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nkallen-cache-money
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Kallen
|
@@ -17,7 +17,7 @@ dependencies:
|
|
17
17
|
version_requirement:
|
18
18
|
version_requirements: !ruby/object:Gem::Requirement
|
19
19
|
requirements:
|
20
|
-
- - "
|
20
|
+
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 2.2.0
|
23
23
|
version:
|
@@ -26,10 +26,19 @@ dependencies:
|
|
26
26
|
version_requirement:
|
27
27
|
version_requirements: !ruby/object:Gem::Requirement
|
28
28
|
requirements:
|
29
|
-
- - "
|
29
|
+
- - ">="
|
30
30
|
- !ruby/object:Gem::Version
|
31
31
|
version: 2.2.0
|
32
32
|
version:
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: memcache-client
|
35
|
+
version_requirement:
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.5.0
|
41
|
+
version:
|
33
42
|
description: Cache utilities.
|
34
43
|
email: nick@twitter.com
|
35
44
|
executables: []
|