active_remote-cached 1.2.0 → 1.3.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
  SHA256:
3
- metadata.gz: db04ead0732ea2b7c372a7c7f674a8d3450c483a05688a56ee3684f2dc7c2688
4
- data.tar.gz: 6d0823e6ff844c6effb2da7dddc15353da1240a694cc88324a1ed9c1d273189c
3
+ metadata.gz: b076da51dcb6fbb2bea19dda19448c84e054f71b55c04790a04e892d3f7f5cba
4
+ data.tar.gz: dcaeb090f4125596ab16c923afe2dd7034bb54d25dadccb4b604a0956111e492
5
5
  SHA512:
6
- metadata.gz: 760fe52b8cc4b6b1e3f5d7bb61af29567f0a8deb99ea0d4b29941bed11f293c1ef43667dcbefb9bf7a18423680871b7dbcd19ef314a9a7e58976385ae0305d59
7
- data.tar.gz: 544d6d1e7d17afb3bb125af5d2e66efd41eae5676cd6984491fa9c611d0a0c258e8e8a69020adb13b9ad240dd4f4ab46e548defcd6b06194eee4789ee4402868
6
+ metadata.gz: 2ba115560d1beb045ed0bee808032dfaaf1c01829d6078be27437ef89ccbfeb28a169b5a3c701d0afcfd103e8f0a9bc0bef133083a5c0b74c6be61c8eaad8c56
7
+ data.tar.gz: 2f2599b18d3e6f3b655051a387a08ca2b66f11d1af0921201dcfff95b116181751e7cc5298f9a8d996378af9c3fc2c9f8ea7137479a3763f382dc03abc03b0ea
data/README.md CHANGED
@@ -80,7 +80,25 @@ The default cache options used when interacting with the cache can be specified
80
80
  ActiveRemote::Cached.default_options(:expires_in => 1.hour)
81
81
  ```
82
82
 
83
- In Rails apps, the :race_condition_ttl option defaults to 5 seconds.
83
+ In Rails apps, the railtie sets `:expires_in` to 5 minutes and `:race_condition_ttl` to 5 seconds. Change them with `config.active_remote_cached.expires_in` and `config.active_remote_cached.race_condition_ttl`.
84
+
85
+ `default_options` merges the given options into the current options. An initializer that adds one option keeps the railtie's TTL:
86
+
87
+ ```ruby
88
+ # config/initializers/active_remote_cached.rb
89
+ ActiveRemote::Cached.default_options(:active_remote_cached_replace_characters => true)
90
+ ActiveRemote::Cached.default_options
91
+ # => { :expires_in => 5.minutes, :race_condition_ttl => 5.seconds, :active_remote_cached_replace_characters => true }
92
+ ```
93
+
94
+ To replace all the options, use `default_options_overwrite`. Pass an empty hash to clear them:
95
+
96
+ ```ruby
97
+ ActiveRemote::Cached.default_options_overwrite(:expires_in => 1.hour)
98
+ ActiveRemote::Cached.default_options_overwrite({})
99
+ ```
100
+
101
+ Without `:expires_in`, a cached finder writes an entry that never expires.
84
102
 
85
103
  #### Local overrides
86
104
 
@@ -149,6 +167,30 @@ CI runs this matrix on Ruby 3.1, Ruby 3.4, JRuby 9.4, and JRuby 10.0.
149
167
  `active_remote` 8.0 requires Ruby 3.2 or later. CI does not run that
150
168
  version on Ruby 3.1 or JRuby 9.4.
151
169
 
170
+ ## Upgrading to 1.3.0
171
+
172
+ ### default_options merges
173
+
174
+ Before 1.3.0, each call to `default_options` replaced the options. In a
175
+ Rails app, the railtie sets `:expires_in` and `:race_condition_ttl` before the
176
+ app initializers run. An initializer that called `default_options` with other
177
+ options removed the TTL, and every cached finder call with no `:expires_in`
178
+ wrote an entry that never expired:
179
+
180
+ ```ruby
181
+ # railtie: { :expires_in => 5.minutes, :race_condition_ttl => 5.seconds }
182
+ ActiveRemote::Cached.default_options(:active_remote_cached_replace_characters => true)
183
+ # before: { :active_remote_cached_replace_characters => true }
184
+ # now: { :expires_in => 5.minutes, :race_condition_ttl => 5.seconds, :active_remote_cached_replace_characters => true }
185
+ ```
186
+
187
+ After the upgrade, an app like this gets a TTL again. Its finders call the
188
+ remote service more often, because entries now expire.
189
+
190
+ `default_options({})` no longer clears the options. Use
191
+ `default_options_overwrite({})`. Use `default_options_overwrite` to keep the
192
+ old replace behavior.
193
+
152
194
  ## Upgrading to 1.2.0
153
195
 
154
196
  ### Every cache key changes
@@ -6,20 +6,18 @@ lib = File.expand_path('lib', __dir__)
6
6
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
7
7
  require 'active_remote/cached/version'
8
8
 
9
- HOMEPAGE = 'https://github.com/mxenabled/active_remote-cached'
9
+ # Locals, not a constant or a def: `gem build` evals this file inside
10
+ # Gem::Specification, so top-level definitions land on that class.
11
+ homepage = 'https://github.com/mxenabled/active_remote-cached'
10
12
 
11
13
  # git ls-files returns nothing outside a checkout, so a build from a released
12
14
  # tarball needs the glob.
13
- def gem_files
14
- files = if File.directory?(File.join(__dir__, '.git'))
15
- `git ls-files`.split($INPUT_RECORD_SEPARATOR)
16
- else
17
- Dir.glob('{lib,spec}/**/*', File::FNM_DOTMATCH) +
18
- %w[LICENSE.txt README.md Rakefile Appraisals active_remote-cached.gemspec]
19
- end
20
-
21
- files.reject { |file| File.directory?(file) }
22
- end
15
+ gem_files = if File.directory?(File.join(__dir__, '.git'))
16
+ `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
+ else
18
+ Dir.glob('{lib,spec}/**/*', File::FNM_DOTMATCH) +
19
+ %w[LICENSE.txt README.md Rakefile Appraisals active_remote-cached.gemspec]
20
+ end
23
21
 
24
22
  Gem::Specification.new do |gem|
25
23
  gem.name = 'active_remote-cached'
@@ -28,17 +26,17 @@ Gem::Specification.new do |gem|
28
26
  gem.email = ['brandonsdewitt@gmail.com', 'devexperience@mx.com']
29
27
  gem.description = ' Provides "cached" finders and a DSL to enumerate which finders should have cached versions '
30
28
  gem.summary = ' Provides a configuration for caching mechanisms and finders on ActiveRemote models'
31
- gem.homepage = HOMEPAGE
29
+ gem.homepage = homepage
32
30
  gem.license = 'MIT'
33
31
 
34
32
  gem.metadata = {
35
- 'homepage_uri' => HOMEPAGE,
36
- 'source_code_uri' => HOMEPAGE,
33
+ 'homepage_uri' => homepage,
34
+ 'source_code_uri' => homepage,
37
35
  'rubygems_mfa_required' => 'true'
38
36
  }
39
37
 
40
38
  gem.required_ruby_version = '>= 3.1'
41
- gem.files = gem_files
39
+ gem.files = gem_files.reject { |file| File.directory?(file) }
42
40
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
43
41
  gem.require_paths = ['lib']
44
42
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveRemote
4
4
  module Cached
5
- VERSION = '1.2.0'
5
+ VERSION = '1.3.0'
6
6
  end
7
7
  end
@@ -31,12 +31,21 @@ module ActiveRemote
31
31
  @cache_provider
32
32
  end
33
33
 
34
+ # Merges the given options into the current options, and returns the
35
+ # result. A later call adds to the options, so an app initializer keeps the
36
+ # :expires_in and :race_condition_ttl that the Rails railtie set before it.
34
37
  def self.default_options(options = nil)
35
- @default_options = options if options
38
+ @default_options = default_options.merge(options) if options
36
39
 
37
40
  @default_options || {}
38
41
  end
39
42
 
43
+ # Replaces the current options with the given options, and returns them.
44
+ # Pass an empty hash to clear the options.
45
+ def self.default_options_overwrite(options)
46
+ @default_options = options.dup
47
+ end
48
+
40
49
  module ClassMethods
41
50
  def cached_methods
42
51
  @cached_methods ||= []
@@ -56,7 +56,7 @@ describe DeleteMethodClass do
56
56
  end
57
57
 
58
58
  after do
59
- ::ActiveRemote::Cached.default_options({})
59
+ ::ActiveRemote::Cached.default_options_overwrite({})
60
60
  end
61
61
 
62
62
  it 'deletes the find cache key' do
@@ -141,7 +141,7 @@ describe ExistMethodClass do
141
141
  end
142
142
 
143
143
  after do
144
- ::ActiveRemote::Cached.default_options({})
144
+ ::ActiveRemote::Cached.default_options_overwrite({})
145
145
  end
146
146
 
147
147
  it 'returns false before the find cache key is written' do
@@ -186,7 +186,7 @@ describe ExistMethodClass do
186
186
  end
187
187
 
188
188
  after do
189
- ::ActiveRemote::Cached.default_options({})
189
+ ::ActiveRemote::Cached.default_options_overwrite({})
190
190
  end
191
191
 
192
192
  it 'returns false before the search cache key is written' do
@@ -64,7 +64,7 @@ describe FindMethodClass do
64
64
  end
65
65
 
66
66
  after do
67
- ::ActiveRemote::Cached.default_options({})
67
+ ::ActiveRemote::Cached.default_options_overwrite({})
68
68
  end
69
69
 
70
70
  it 'executes find_by_guid when cached_find with guid called' do
@@ -117,7 +117,7 @@ describe FindMethodClass do
117
117
  end
118
118
 
119
119
  after do
120
- ::ActiveRemote::Cached.default_options({})
120
+ ::ActiveRemote::Cached.default_options_overwrite({})
121
121
  end
122
122
 
123
123
  it 'overrides the default options with cached_finder options for the fetch call' do
@@ -95,7 +95,7 @@ describe SearchMethodClass do
95
95
  end
96
96
 
97
97
  after do
98
- ::ActiveRemote::Cached.default_options({})
98
+ ::ActiveRemote::Cached.default_options_overwrite({})
99
99
  end
100
100
 
101
101
  it 'executes the search block when a block is passed' do
@@ -203,7 +203,7 @@ describe SearchMethodClass do
203
203
  end
204
204
 
205
205
  after do
206
- ::ActiveRemote::Cached.default_options({})
206
+ ::ActiveRemote::Cached.default_options_overwrite({})
207
207
  end
208
208
 
209
209
  it 'overrides the default options with cached_finder options for the fetch call' do
@@ -232,7 +232,7 @@ describe SearchMethodClass do
232
232
  end
233
233
 
234
234
  after do
235
- ::ActiveRemote::Cached.default_options({})
235
+ ::ActiveRemote::Cached.default_options_overwrite({})
236
236
  end
237
237
 
238
238
  it 'and_return results when present' do
@@ -307,7 +307,7 @@ describe SearchMethodClass do
307
307
  end
308
308
 
309
309
  after do
310
- ::ActiveRemote::Cached.default_options({})
310
+ ::ActiveRemote::Cached.default_options_overwrite({})
311
311
  end
312
312
 
313
313
  it 'calls the underlying method with params in correct order' do
@@ -65,7 +65,7 @@ describe ::ActiveRemote::Cached do
65
65
  end
66
66
 
67
67
  after do
68
- ::ActiveRemote::Cached.default_options({})
68
+ ::ActiveRemote::Cached.default_options_overwrite({})
69
69
  end
70
70
 
71
71
  describe '.cache' do
@@ -91,17 +91,76 @@ describe ::ActiveRemote::Cached do
91
91
  expect(::ActiveRemote::Cached.default_options).to eq(:expires_in => 100)
92
92
  end
93
93
 
94
- # Passing nil reads the options. Callers must pass an empty hash to clear.
95
94
  it 'keeps the current options when nil is given' do
96
95
  ::ActiveRemote::Cached.default_options(:expires_in => 100)
97
96
 
98
97
  expect(::ActiveRemote::Cached.default_options(nil)).to eq(:expires_in => 100)
99
98
  end
100
99
 
100
+ it 'keeps the current options when an empty hash is given' do
101
+ ::ActiveRemote::Cached.default_options(:expires_in => 100)
102
+
103
+ expect(::ActiveRemote::Cached.default_options({})).to eq(:expires_in => 100)
104
+ end
105
+
106
+ # The Rails railtie sets :expires_in and :race_condition_ttl. An app
107
+ # initializer that sets one more option must not remove them.
108
+ it 'merges the given options into the current options' do
109
+ ::ActiveRemote::Cached.default_options(:expires_in => 100, :race_condition_ttl => 5)
110
+ ::ActiveRemote::Cached.default_options(:active_remote_cached_replace_characters => true)
111
+
112
+ expect(::ActiveRemote::Cached.default_options).to eq(
113
+ :expires_in => 100,
114
+ :race_condition_ttl => 5,
115
+ :active_remote_cached_replace_characters => true
116
+ )
117
+ end
118
+
119
+ it 'lets the given options win over the current options' do
120
+ ::ActiveRemote::Cached.default_options(:expires_in => 100)
121
+ ::ActiveRemote::Cached.default_options(:expires_in => 200)
122
+
123
+ expect(::ActiveRemote::Cached.default_options).to eq(:expires_in => 200)
124
+ end
125
+
126
+ it 'does not change a hash that the caller passed' do
127
+ first = { :expires_in => 100 }
128
+ ::ActiveRemote::Cached.default_options(first)
129
+ ::ActiveRemote::Cached.default_options(:race_condition_ttl => 5)
130
+
131
+ expect(first).to eq(:expires_in => 100)
132
+ end
133
+
134
+ it 'gives each finder call the merged options' do
135
+ ::ActiveRemote::Cached.default_options(:expires_in => 100)
136
+ ::ActiveRemote::Cached.default_options(:active_remote_cached_replace_characters => true)
137
+
138
+ expect(::ActiveRemote::Cached.cache).to receive(:fetch).with(
139
+ [versioned_prefix, ConfigurationClass.name, '#find', 'guid.guid'],
140
+ { :expires_in => 100, :active_remote_cached_replace_characters => true }
141
+ ).and_return(:find_result)
142
+
143
+ ConfigurationClass.cached_find_by_guid(:guid)
144
+ end
145
+ end
146
+
147
+ describe '.default_options_overwrite' do
148
+ it 'replaces the current options' do
149
+ ::ActiveRemote::Cached.default_options(:expires_in => 100, :race_condition_ttl => 5)
150
+ ::ActiveRemote::Cached.default_options_overwrite(:active_remote_cached_replace_characters => true)
151
+
152
+ expect(::ActiveRemote::Cached.default_options).to eq(:active_remote_cached_replace_characters => true)
153
+ end
154
+
101
155
  it 'clears the current options when an empty hash is given' do
102
156
  ::ActiveRemote::Cached.default_options(:expires_in => 100)
157
+ ::ActiveRemote::Cached.default_options_overwrite({})
158
+
159
+ expect(::ActiveRemote::Cached.default_options).to eq({})
160
+ end
103
161
 
104
- expect(::ActiveRemote::Cached.default_options({})).to eq({})
162
+ it 'returns the new options' do
163
+ expect(::ActiveRemote::Cached.default_options_overwrite(:expires_in => 100)).to eq(:expires_in => 100)
105
164
  end
106
165
  end
107
166
 
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'open3'
5
+
6
+ # `gem build` evals the gemspec inside Gem::Specification, but Bundler evals it
7
+ # at the top level. Bundler has already loaded the gemspec in this process, so
8
+ # a top-level def or constant from that load would hide the bug here. Load it
9
+ # in a fresh ruby without Bundler instead.
10
+ describe 'active_remote-cached.gemspec' do
11
+ let(:root) { File.expand_path('..', __dir__) }
12
+ let(:script) do
13
+ <<~RUBY
14
+ spec = Gem::Specification.load('active_remote-cached.gemspec')
15
+ abort 'Gem::Specification.load returned nil' unless spec
16
+ spec.validate
17
+ puts spec.full_name
18
+ RUBY
19
+ end
20
+
21
+ it 'loads and validates with Rubygems alone' do
22
+ stdout, stderr, status = ::Bundler.with_unbundled_env do
23
+ ::Open3.capture3(::RbConfig.ruby, '-e', script, :chdir => root)
24
+ end
25
+
26
+ expect(status).to be_success, stderr
27
+ expect(stdout).to eq("active_remote-cached-#{::ActiveRemote::Cached::VERSION}\n")
28
+ end
29
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_remote-cached
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Dewitt
@@ -181,6 +181,7 @@ files:
181
181
  - spec/active_remote/cached_find_methods_spec.rb
182
182
  - spec/active_remote/cached_search_methods_spec.rb
183
183
  - spec/active_remote/cached_spec.rb
184
+ - spec/gemspec_spec.rb
184
185
  - spec/spec_helper.rb
185
186
  homepage: https://github.com/mxenabled/active_remote-cached
186
187
  licenses:
@@ -203,7 +204,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
203
204
  - !ruby/object:Gem::Version
204
205
  version: '0'
205
206
  requirements: []
206
- rubygems_version: 3.6.9
207
+ rubygems_version: 4.0.15
207
208
  specification_version: 4
208
209
  summary: Provides a configuration for caching mechanisms and finders on ActiveRemote
209
210
  models