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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 487f736bf28cb7076dac918d31e3bea6c1cfb8e9
4
- data.tar.gz: d7ba6df09f50de96fe22b27193d3dfad0525751f
3
+ metadata.gz: 1eca8358ecaf741c5815a28a6647a528b316df8c
4
+ data.tar.gz: af038164c54204cc910039bc035d501e729ec69a
5
5
  SHA512:
6
- metadata.gz: c418ab5a7584b586d285565113b788326c69518123cdfa0b7a6cc4f55b4f754fc8be807de2044a94f04275b66940f2178a3e96be4109b83209596f6136c79307
7
- data.tar.gz: 61813326dfabf36d852481cae061b9bd9739fdf793619451285bb8aab04cd9b2b749e6cf4f205ec123fd0585a7ebe535e9b64a9e9f1ff324d4e91cdfab181273
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: 15
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
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  source 'https://rubygems.org'
3
4
  gemspec
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.del('hello_')
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 extend `Object` with a `cache` method, for
213
- convenient access to the cache object:
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(--display-cop-names --extra-details --display-style-guide)
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(test rubocop)
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
- key = build_key(key, key_prefix, Proc.new)
51
-
52
- if (cached_value = replica.get(key)).nil?
53
- yield.tap { |value| update_cache(key, value, ttl: ttl) }
54
- else
55
- Marshal.load(cached_value)
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}" == proc.source_location.join }
111
- location && location.base_label
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
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'object/cache'
3
4
 
4
5
  # :no-doc:
5
- class Object
6
+ module Kernel
6
7
  def cache(key = nil, **options, &block)
7
- block = -> { self } unless block_given?
8
-
9
8
  Cache.new(key, **options, &block)
10
9
  end
11
10
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Cache
4
- VERSION = '0.0.5'
4
+ VERSION = '0.1.0'
5
5
  end
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(Jean Mertz)
11
- spec.email = %w(jean@mertz.fm)
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(lib)
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 'hello world', Cache.new { 'hello world' }
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 'hello world', cache { 'hello world' }
98
- assert Object.send(:remove_method, :cache)
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 Object.send(:remove_method, :cache)
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.5
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: 2016-05-26 00:00:00.000000000 Z
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.4
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.