active_remote-cached 1.0.0 → 1.2.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/.github/workflows/ci.yml +85 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +58 -0
- data/Appraisals +27 -0
- data/Gemfile +2 -0
- data/README.md +121 -0
- data/Rakefile +6 -9
- data/active_remote-cached.gemspec +52 -21
- data/lib/active_remote/cached/argument_keys.rb +83 -46
- data/lib/active_remote/cached/cache.rb +78 -51
- data/lib/active_remote/cached/railtie.rb +5 -5
- data/lib/active_remote/cached/version.rb +3 -1
- data/lib/active_remote/cached.rb +159 -112
- data/lib/active_remote-cached.rb +3 -1
- data/spec/active_remote/cached/argument_keys_spec.rb +136 -10
- data/spec/active_remote/cached/cache_spec.rb +179 -16
- data/spec/active_remote/cached_delete_methods_spec.rb +66 -12
- data/spec/active_remote/cached_exist_methods_spec.rb +111 -33
- data/spec/active_remote/cached_find_methods_spec.rb +62 -51
- data/spec/active_remote/cached_search_methods_spec.rb +202 -102
- data/spec/active_remote/cached_spec.rb +331 -0
- data/spec/spec_helper.rb +6 -10
- metadata +76 -22
|
@@ -1,72 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'delegate'
|
|
2
4
|
|
|
3
|
-
module ActiveRemote
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
module ActiveRemote
|
|
6
|
+
module Cached
|
|
7
|
+
class Cache < ::SimpleDelegator
|
|
8
|
+
# Raised when the given cache provider is missing a method the library
|
|
9
|
+
# calls on it.
|
|
10
|
+
class InvalidCacheProvider < ::StandardError; end
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
@cache_provider = new_cache_provider
|
|
9
|
-
@nested_cache_provider = ::ActiveSupport::Cache::NullStore.new
|
|
12
|
+
attr_reader :cache_provider
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
validate_provider_method_present(:read)
|
|
15
|
-
validate_provider_method_present(:write)
|
|
14
|
+
def initialize(new_cache_provider)
|
|
15
|
+
@cache_provider = new_cache_provider
|
|
16
|
+
@nested_cache_provider = ::ActiveSupport::Cache::NullStore.new
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
validate_provider_method_present(:delete)
|
|
19
|
+
validate_provider_method_present(:exist?)
|
|
20
|
+
validate_provider_method_present(:fetch)
|
|
21
|
+
validate_provider_method_present(:read)
|
|
22
|
+
validate_provider_method_present(:write)
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
super
|
|
23
|
-
end
|
|
24
|
+
super(@cache_provider)
|
|
25
|
+
end
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
def delete(*args)
|
|
28
|
+
nested_cache_provider.delete(*args)
|
|
29
|
+
super
|
|
30
|
+
end
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
def enable_nested_caching!
|
|
33
|
+
@nested_cache_provider = ::ActiveSupport::Cache::MemoryStore.new
|
|
34
|
+
end
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
def nested_caching?
|
|
37
|
+
!nested_cache_provider.is_a?(::ActiveSupport::Cache::NullStore)
|
|
38
|
+
end
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
def exist?(*args)
|
|
41
|
+
nested_cache_provider.exist?(*args) || super
|
|
38
42
|
end
|
|
39
43
|
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
def fetch(name, options = {})
|
|
45
|
+
provider_options = provider_fetch_options(options)
|
|
46
|
+
fetch_value = nested_cache_provider.fetch(name, provider_options) { super(name, provider_options) }
|
|
42
47
|
|
|
43
|
-
|
|
44
|
-
nested_cache_provider.read(*args) || super
|
|
45
|
-
end
|
|
48
|
+
delete(name) if delete_after_fetch?(fetch_value, options, provider_options)
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
fetch_value
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def read(*args)
|
|
54
|
+
nested_cache_provider.read(*args) || super
|
|
55
|
+
end
|
|
51
56
|
|
|
52
|
-
|
|
57
|
+
def write(*args)
|
|
58
|
+
nested_cache_provider.write(*args)
|
|
59
|
+
super
|
|
60
|
+
end
|
|
53
61
|
|
|
54
|
-
|
|
55
|
-
@nested_cache_provider
|
|
56
|
-
end
|
|
62
|
+
private
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
attr_reader :nested_cache_provider
|
|
65
|
+
|
|
66
|
+
# :skip_nil tells the provider not to write a nil at all, which saves a
|
|
67
|
+
# write and the delete that follows it. Only an ActiveSupport store is
|
|
68
|
+
# known to honor the option.
|
|
69
|
+
def provider_fetch_options(options)
|
|
70
|
+
return options if options.fetch(:allow_nil, false)
|
|
71
|
+
return options unless cache_provider.is_a?(::ActiveSupport::Cache::Store)
|
|
72
|
+
|
|
73
|
+
options.merge(:skip_nil => true)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def delete_after_fetch?(value, options, provider_options)
|
|
77
|
+
return false if valid_fetched_value?(value, options)
|
|
78
|
+
# The provider already skipped the write.
|
|
79
|
+
return false if value.nil? && provider_options[:skip_nil]
|
|
80
|
+
|
|
81
|
+
true
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def valid_fetched_value?(value, options = {})
|
|
85
|
+
return false if value.nil? && !options.fetch(:allow_nil, false)
|
|
86
|
+
return false if !options.fetch(:allow_empty, false) && value.respond_to?(:empty?) && value.empty?
|
|
87
|
+
|
|
88
|
+
true
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def validate_provider_method_present(method_name)
|
|
92
|
+
return if cache_provider.respond_to?(method_name)
|
|
63
93
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
ActiveRemote::Cached::Cache must respond_to? #{method_name}
|
|
68
|
-
in order to be used as a caching interface for ActiveRemote
|
|
69
|
-
CACHE_METHOD
|
|
94
|
+
raise InvalidCacheProvider,
|
|
95
|
+
"ActiveRemote::Cached::Cache must respond_to? #{method_name} " \
|
|
96
|
+
'in order to be used as a caching interface for ActiveRemote'
|
|
70
97
|
end
|
|
71
98
|
end
|
|
72
99
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'active_support/ordered_options'
|
|
2
4
|
|
|
3
5
|
module ActiveRemote
|
|
@@ -5,18 +7,16 @@ module ActiveRemote
|
|
|
5
7
|
class Railtie < ::Rails::Railtie
|
|
6
8
|
config.active_remote_cached = ::ActiveSupport::OrderedOptions.new
|
|
7
9
|
|
|
8
|
-
initializer
|
|
10
|
+
initializer 'active_remote-cached.initialize_cache' do |_app|
|
|
9
11
|
config.active_remote_cached.expires_in ||= 5.minutes
|
|
10
12
|
config.active_remote_cached.race_condition_ttl ||= 5.seconds
|
|
11
13
|
|
|
12
14
|
::ActiveRemote::Cached.cache(Rails.cache)
|
|
13
15
|
|
|
14
|
-
if config.active_remote_cached.enable_nested_caching
|
|
15
|
-
::ActiveRemote::Cached.cache.enable_nested_caching!
|
|
16
|
-
end
|
|
16
|
+
::ActiveRemote::Cached.cache.enable_nested_caching! if config.active_remote_cached.enable_nested_caching
|
|
17
17
|
|
|
18
18
|
::ActiveRemote::Cached.default_options(
|
|
19
|
-
:expires_in
|
|
19
|
+
:expires_in => config.active_remote_cached.expires_in,
|
|
20
20
|
:race_condition_ttl => config.active_remote_cached.race_condition_ttl
|
|
21
21
|
)
|
|
22
22
|
end
|