object-cache 0.0.5 → 0.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +11 -1
- data/Gemfile +1 -0
- data/README.md +4 -12
- data/Rakefile +3 -2
- data/lib/object/cache.rb +25 -17
- data/lib/object/cache/core_extension.rb +2 -3
- data/lib/object/cache/version.rb +1 -1
- data/object-cache.gemspec +4 -3
- data/test/cache_test.rb +54 -17
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1eca8358ecaf741c5815a28a6647a528b316df8c
|
4
|
+
data.tar.gz: af038164c54204cc910039bc035d501e729ec69a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 338d80cb2a6fd6c1720003655d23770074cca0a0df1f958805ffcf6987016748aa1cb39e8ad59b0fdca0227a19f9810dd026c3c8786e861c26d6828e8d3502d0
|
7
|
+
data.tar.gz: 88d4a44e5d94dc74bcb46d4ce81056871dd9c9e1a592ff8a929f1dc8347fadefdd1399072eec16e5e876f2f22d2c2ef8d4a90344f0986131c78eac05346b36f5
|
data/.rubocop.yml
CHANGED
@@ -4,7 +4,17 @@ AllCops:
|
|
4
4
|
- '.wercker/**/*'
|
5
5
|
|
6
6
|
Metrics/MethodLength:
|
7
|
-
Max:
|
7
|
+
Max: 20
|
8
8
|
|
9
9
|
Metrics/LineLength:
|
10
10
|
Max: 100
|
11
|
+
|
12
|
+
Lint/RescueWithoutErrorClass:
|
13
|
+
Exclude:
|
14
|
+
- 'lib/object/cache.rb'
|
15
|
+
- 'test/cache_test.rb'
|
16
|
+
|
17
|
+
Security/MarshalLoad:
|
18
|
+
Exclude:
|
19
|
+
- 'lib/object/cache.rb'
|
20
|
+
- 'test/cache_test.rb'
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -157,7 +157,8 @@ Cache.backend.keys # => ["hello_22abcc"]
|
|
157
157
|
This allows you to selectively purge keys from Redis:
|
158
158
|
|
159
159
|
```ruby
|
160
|
-
Cache.backend.
|
160
|
+
keys = Cache.backend.keys('hello_*')
|
161
|
+
Cache.backend.del(keys)
|
161
162
|
```
|
162
163
|
|
163
164
|
You can also use the special value `:method_name` to dynamically set the key
|
@@ -209,8 +210,8 @@ from the primary instance.
|
|
209
210
|
|
210
211
|
#### core extension
|
211
212
|
|
212
|
-
Finally, if you want, you can
|
213
|
-
|
213
|
+
Finally, if you want, you can use the `cache` method, for convenient
|
214
|
+
access to the cache object:
|
214
215
|
|
215
216
|
```ruby
|
216
217
|
require 'object/cache/core_extension'
|
@@ -220,15 +221,6 @@ cache('hello', ttl: 60) { 'hello world' }
|
|
220
221
|
Cache.new('hello', ttl: 60) { 'hello world' }
|
221
222
|
```
|
222
223
|
|
223
|
-
You can also call this method directly on any instances inheriting from
|
224
|
-
`Object`:
|
225
|
-
|
226
|
-
```ruby
|
227
|
-
require 'object/cache/core_extension'
|
228
|
-
|
229
|
-
'hello world'.cache(ttl: 60)
|
230
|
-
```
|
231
|
-
|
232
224
|
That's it!
|
233
225
|
|
234
226
|
## License
|
data/Rakefile
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'bundler/gem_tasks'
|
3
4
|
require 'rake/testtask'
|
4
5
|
require 'rubocop/rake_task'
|
5
6
|
|
6
7
|
RuboCop::RakeTask.new do |t|
|
7
|
-
t.options = %w
|
8
|
+
t.options = %w[--display-cop-names --extra-details --display-style-guide]
|
8
9
|
end
|
9
10
|
|
10
11
|
Rake::TestTask.new(:test) do |t|
|
@@ -13,4 +14,4 @@ Rake::TestTask.new(:test) do |t|
|
|
13
14
|
t.test_files = FileList['test/**/*_test.rb']
|
14
15
|
end
|
15
16
|
|
16
|
-
task default: %i
|
17
|
+
task default: %i[test rubocop]
|
data/lib/object/cache.rb
CHANGED
@@ -47,22 +47,30 @@ class Cache
|
|
47
47
|
def new(key = nil, ttl: default_ttl, key_prefix: default_key_prefix)
|
48
48
|
return yield unless replica
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
begin
|
51
|
+
key = build_key(key, key_prefix, Proc.new)
|
52
|
+
|
53
|
+
if (cached_value = replica.get(key)).nil?
|
54
|
+
yield.tap do |value|
|
55
|
+
begin
|
56
|
+
update_cache(key, value, ttl: ttl)
|
57
|
+
rescue TypeError
|
58
|
+
# if `TypeError` is raised, the data could not be Marshal dumped. In that
|
59
|
+
# case, delete anything left in the cache store, and get the data without
|
60
|
+
# caching.
|
61
|
+
#
|
62
|
+
delete(key)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
else
|
66
|
+
begin
|
67
|
+
Marshal.load(cached_value)
|
68
|
+
rescue
|
69
|
+
delete(key)
|
70
|
+
yield
|
71
|
+
end
|
72
|
+
end
|
56
73
|
end
|
57
|
-
rescue TypeError
|
58
|
-
# if `TypeError` is raised, the data could not be Marshal dumped. In that
|
59
|
-
# case, delete anything left in the cache store, and get the data without
|
60
|
-
# caching.
|
61
|
-
#
|
62
|
-
delete(key)
|
63
|
-
yield
|
64
|
-
rescue
|
65
|
-
yield
|
66
74
|
end
|
67
75
|
|
68
76
|
def include?(key)
|
@@ -107,8 +115,8 @@ class Cache
|
|
107
115
|
def build_key_prefix(key_prefix, proc)
|
108
116
|
case key_prefix
|
109
117
|
when :method_name
|
110
|
-
location = caller_locations.find { |l| "#{l.path}#{l.lineno}"
|
111
|
-
location
|
118
|
+
location = caller_locations.find { |l| proc.source_location.join == "#{l.path}#{l.lineno}" }
|
119
|
+
location&.base_label
|
112
120
|
when :class_name
|
113
121
|
proc.binding.receiver.class.to_s
|
114
122
|
else
|
data/lib/object/cache/version.rb
CHANGED
data/object-cache.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
# encoding: utf-8
|
3
|
+
|
3
4
|
lib = File.expand_path('../lib', __FILE__)
|
4
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
6
|
require 'object/cache'
|
@@ -7,15 +8,15 @@ require 'object/cache'
|
|
7
8
|
Gem::Specification.new do |spec|
|
8
9
|
spec.name = 'object-cache'
|
9
10
|
spec.version = Cache::VERSION
|
10
|
-
spec.authors = %w
|
11
|
-
spec.email = %w
|
11
|
+
spec.authors = %w[Jean Mertz]
|
12
|
+
spec.email = %w[jean@mertz.fm]
|
12
13
|
|
13
14
|
spec.summary = 'Caching of objects, using a Redis store.'
|
14
15
|
spec.description = 'Easily cache objects in Ruby, using a Redis store backend'
|
15
16
|
spec.homepage = 'https://github.com/blendle/object-cache'
|
16
17
|
spec.license = 'MIT'
|
17
18
|
spec.files = `git ls-files -z`.split("\x0")
|
18
|
-
spec.require_paths = %w
|
19
|
+
spec.require_paths = %w[lib]
|
19
20
|
|
20
21
|
spec.add_development_dependency 'bundler', '~> 1.12'
|
21
22
|
spec.add_development_dependency 'm', '~> 1.5'
|
data/test/cache_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
3
4
|
|
4
5
|
require 'mock_redis'
|
@@ -21,7 +22,7 @@ class CacheTest < Minitest::Test # rubocop:disable Metrics/ClassLength
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def test_cache_returns_object
|
24
|
-
assert_equal
|
25
|
+
assert_equal('hello world', Cache.new { 'hello world' })
|
25
26
|
end
|
26
27
|
|
27
28
|
def test_cache_stores_object
|
@@ -94,28 +95,15 @@ class CacheTest < Minitest::Test # rubocop:disable Metrics/ClassLength
|
|
94
95
|
|
95
96
|
def test_core_extension
|
96
97
|
load 'object/cache/core_extension.rb'
|
97
|
-
assert_equal
|
98
|
-
assert
|
98
|
+
assert_equal('hello world', cache { 'hello world' })
|
99
|
+
assert Kernel.send(:remove_method, :cache)
|
99
100
|
end
|
100
101
|
|
101
102
|
def test_core_extension_options
|
102
103
|
load 'object/cache/core_extension.rb'
|
103
104
|
cache(ttl: 60) { 'hello world' }
|
104
105
|
assert_equal 60, redis.ttl(redis.keys.first)
|
105
|
-
assert
|
106
|
-
end
|
107
|
-
|
108
|
-
def test_core_extension_on_objects
|
109
|
-
load 'object/cache/core_extension.rb'
|
110
|
-
assert_equal 'hello world', 'hello world'.cache
|
111
|
-
assert Object.send(:remove_method, :cache)
|
112
|
-
end
|
113
|
-
|
114
|
-
def test_core_extension_on_objects_with_arguments
|
115
|
-
load 'object/cache/core_extension.rb'
|
116
|
-
'hello world'.cache(ttl: 30)
|
117
|
-
assert_equal 30, redis.ttl(redis.keys.first)
|
118
|
-
assert Object.send(:remove_method, :cache)
|
106
|
+
assert Kernel.send(:remove_method, :cache)
|
119
107
|
end
|
120
108
|
|
121
109
|
def test_backend_with_replicas
|
@@ -183,4 +171,53 @@ class CacheTest < Minitest::Test # rubocop:disable Metrics/ClassLength
|
|
183
171
|
Cache.new(key_prefix: :class_name) { 'hello world' }
|
184
172
|
assert_match(/^CacheTest/, redis.keys.first)
|
185
173
|
end
|
174
|
+
|
175
|
+
def test_unset_backend
|
176
|
+
Cache.backend = nil
|
177
|
+
val = 0
|
178
|
+
block = -> { val += 1 }
|
179
|
+
Cache.new(&block)
|
180
|
+
Cache.backend = MockRedis.new
|
181
|
+
|
182
|
+
assert_equal 1, val
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_unset_backend_raising_type_error
|
186
|
+
Cache.backend = nil
|
187
|
+
val = 0
|
188
|
+
begin
|
189
|
+
Cache.new do
|
190
|
+
val += 1
|
191
|
+
raise TypeError
|
192
|
+
end
|
193
|
+
rescue
|
194
|
+
nil
|
195
|
+
end
|
196
|
+
|
197
|
+
Cache.backend = MockRedis.new
|
198
|
+
assert_equal 1, val
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_single_yield_on_failure
|
202
|
+
val = 0
|
203
|
+
begin
|
204
|
+
Cache.new do
|
205
|
+
val += 1
|
206
|
+
raise TypeError
|
207
|
+
end
|
208
|
+
rescue
|
209
|
+
nil
|
210
|
+
end
|
211
|
+
|
212
|
+
assert_equal 1, val
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_yield_when_marshal_load_fails
|
216
|
+
testing = -> { Cache.new(key_prefix: 'marshal') { 'hello world' } }
|
217
|
+
|
218
|
+
assert_equal 'hello world', testing.call
|
219
|
+
redis.set(redis.keys('marshal*').first, 'garbage')
|
220
|
+
assert_equal 'hello world', testing.call
|
221
|
+
assert_empty redis.keys('marshal*')
|
222
|
+
end
|
186
223
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: object-cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2017-09-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -149,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
149
|
version: '0'
|
150
150
|
requirements: []
|
151
151
|
rubyforge_project:
|
152
|
-
rubygems_version: 2.6.
|
152
|
+
rubygems_version: 2.6.11
|
153
153
|
signing_key:
|
154
154
|
specification_version: 4
|
155
155
|
summary: Caching of objects, using a Redis store.
|