active_cached_resource 0.1.5 → 0.1.7
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/CHANGELOG.md +12 -1
- data/lib/active_cached_resource/caching.rb +15 -13
- data/lib/active_cached_resource/caching_strategies/active_support_cache.rb +27 -8
- data/lib/active_cached_resource/caching_strategies/base.rb +31 -8
- data/lib/active_cached_resource/caching_strategies/sql_cache.rb +4 -0
- data/lib/active_cached_resource/collection.rb +1 -1
- data/lib/active_cached_resource/constants.rb +7 -0
- data/lib/active_cached_resource/model.rb +1 -1
- data/lib/active_cached_resource/version.rb +1 -1
- data/lib/active_cached_resource.rb +1 -0
- data/lib/activeresource/lib/active_resource/collection.rb +20 -2
- metadata +7 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45d04dcc0d591d945fbee26f110200f54a889a55516b2340e16f5a53e571d07d
|
4
|
+
data.tar.gz: 9ccf72f8ff91404b52650d199c2ea0569e93b1cc62e830ec2f8551cae8537d23
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a3f42bfc71f0f3abba12204f1bb27ce08389ec6a28d79ca527b95b9bc010eee02bb9f3bc238bbd9a481a3d4f3454b1f05baba48b8885474f92d0778db189975
|
7
|
+
data.tar.gz: 8cda34284a02b73a3c4c3f5a29eb00543c82636340371997af90219d556e80c62056e3d4d50bf7f795680dfd02805c637a4f89c4611a056cffac48c1754e0e81
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,20 @@
|
|
1
|
-
## [0.1.
|
1
|
+
## [0.1.7] - 2024-01-23
|
2
|
+
- Improved `clear_cache` method for `active_support_cache` strategy to no longer use `delete_matched`.
|
3
|
+
- Introduced `.delete_from_cache` method to delete single cached resources.
|
4
|
+
|
5
|
+
## [0.1.6] - 2024-01-15
|
6
|
+
- Renamed `ActiveResource::Collection#refresh` to `#reload` to match Rails ORM naming convention.
|
7
|
+
- Added a `ActiveResource::Collection.none` class method similar to Rails `ActiveRecord::QueryMethods.none`
|
8
|
+
- Enhanced `ActiveResource::Collection#where` so that it returns `ActiveResource::Collection.none` if `resource_class` is missing.
|
9
|
+
- This is useful for when `where` clauses are chained on an empty `ActiveResource::Collection`
|
10
|
+
|
11
|
+
## [0.1.5] - 2024-01-09
|
2
12
|
- Added callbacks to cache:
|
3
13
|
- Create/POST, refresh cache after successful POST request
|
4
14
|
- Update/PUT, refresh cache after successful PUT request
|
5
15
|
- Destroy/DELETE, invalidate cache after successful DELETE request
|
6
16
|
- Fixed issue with generator for SQLCache strategy tables
|
17
|
+
|
7
18
|
## [0.1.4] - 2024-12-20
|
8
19
|
- CI Improvements
|
9
20
|
- Added annotations
|
@@ -2,9 +2,6 @@ require_relative "collection"
|
|
2
2
|
|
3
3
|
module ActiveCachedResource
|
4
4
|
module Caching
|
5
|
-
GLOBAL_PREFIX = "acr"
|
6
|
-
RELOAD_PARAM = :_acr_reload
|
7
|
-
|
8
5
|
extend ActiveSupport::Concern
|
9
6
|
|
10
7
|
included do
|
@@ -128,7 +125,7 @@ module ActiveCachedResource
|
|
128
125
|
# Hacky but this way ActiveCachedResource::Collection#request_resources! can access it
|
129
126
|
if should_reload && args.first == :all
|
130
127
|
options[:params] = {} if options[:params].blank?
|
131
|
-
options[:params][RELOAD_PARAM] = should_reload
|
128
|
+
options[:params][Constants::RELOAD_PARAM] = should_reload
|
132
129
|
args << options
|
133
130
|
end
|
134
131
|
|
@@ -140,13 +137,19 @@ module ActiveCachedResource
|
|
140
137
|
should_reload ? find_via_reload(*args) : find_via_cache(*args)
|
141
138
|
end
|
142
139
|
|
143
|
-
#
|
140
|
+
# Deletes a resource from the cache.
|
141
|
+
#
|
142
|
+
# @param id [Object] the identifier of the resource to be deleted from the cache.
|
143
|
+
def delete_from_cache(id)
|
144
|
+
cached_resource.cache.delete(cache_key(id))
|
145
|
+
end
|
146
|
+
|
147
|
+
# Clears the entire cache for the specified model that matches current prefix.
|
144
148
|
#
|
145
|
-
# @param pattern [String, nil] The pattern to match cache keys against.
|
146
|
-
# If nil, all cache keys with this models prefix will be cleared.
|
147
149
|
# @return [void]
|
148
|
-
def clear_cache
|
149
|
-
cached_resource.
|
150
|
+
def clear_cache
|
151
|
+
cached_resource.logger.debug("Clearing cache for #{name} cache with prefix: #{cache_key_prefix}")
|
152
|
+
cached_resource.cache.clear(cache_key_prefix)
|
150
153
|
end
|
151
154
|
|
152
155
|
private
|
@@ -216,8 +219,7 @@ module ActiveCachedResource
|
|
216
219
|
end
|
217
220
|
|
218
221
|
def name_key
|
219
|
-
#
|
220
|
-
"#{cache_key_prefix}-" + name.parameterize.tr("-", "/")
|
222
|
+
"#{cache_key_prefix}#{Constants::PREFIX_SEPARATOR}#{name.parameterize.tr("-", "/")}"
|
221
223
|
end
|
222
224
|
|
223
225
|
def cache_key_prefix
|
@@ -228,9 +230,9 @@ module ActiveCachedResource
|
|
228
230
|
if !result.is_a?(String) || result.empty?
|
229
231
|
raise ArgumentError, "cache_key_prefix must return a non-empty String"
|
230
232
|
end
|
231
|
-
"#{GLOBAL_PREFIX}/#{result}"
|
233
|
+
"#{Constants::GLOBAL_PREFIX}/#{result}"
|
232
234
|
else
|
233
|
-
"#{GLOBAL_PREFIX}/#{prefix}"
|
235
|
+
"#{Constants::GLOBAL_PREFIX}/#{prefix}"
|
234
236
|
end
|
235
237
|
end
|
236
238
|
|
@@ -15,16 +15,35 @@ module ActiveCachedResource
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def write_raw(key, compressed_value, options)
|
18
|
-
@cache_store.write(key, compressed_value, options)
|
18
|
+
successful_write = @cache_store.write(key, compressed_value, options)
|
19
|
+
update_master_key(key, options) if successful_write
|
20
|
+
|
21
|
+
successful_write
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete_raw(key)
|
25
|
+
@cache_store.delete(key)
|
19
26
|
end
|
20
27
|
|
21
|
-
def clear_raw(
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
def clear_raw(prefix)
|
29
|
+
existing_keys = @cache_store.read(prefix)
|
30
|
+
return if existing_keys.nil?
|
31
|
+
|
32
|
+
existing_keys.add(prefix)
|
33
|
+
@cache_store.delete_multi(existing_keys)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# Updates the `master` key, which contains keys for a given prefix.
|
39
|
+
def update_master_key(key, options)
|
40
|
+
prefix, _ = split_key(key)
|
41
|
+
|
42
|
+
existing_keys = @cache_store.read(prefix) || Set.new
|
43
|
+
existing_keys.add(key)
|
44
|
+
|
45
|
+
# Maintain the list of keys for twice the expiration time
|
46
|
+
@cache_store.write(prefix, existing_keys, expires_in: options[:expires_in])
|
28
47
|
end
|
29
48
|
end
|
30
49
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require "msgpack"
|
2
1
|
module ActiveCachedResource
|
3
2
|
module CachingStrategies
|
4
3
|
class Base
|
@@ -29,6 +28,14 @@ module ActiveCachedResource
|
|
29
28
|
write_raw(hash_key(key), compress(value), options)
|
30
29
|
end
|
31
30
|
|
31
|
+
# Deletes the cached value associated with the given key.
|
32
|
+
#
|
33
|
+
# @param key [Object] the key whose associated cached value is to be deleted.
|
34
|
+
# @return [void]
|
35
|
+
def delete(key)
|
36
|
+
delete_raw(hash_key(key))
|
37
|
+
end
|
38
|
+
|
32
39
|
# Clears the cache based on the given pattern.
|
33
40
|
#
|
34
41
|
# @param pattern [String] the pattern to match cache keys that need to be cleared.
|
@@ -76,6 +83,22 @@ module ActiveCachedResource
|
|
76
83
|
raise NotImplementedError, "#{self.class} must implement `clear_raw`"
|
77
84
|
end
|
78
85
|
|
86
|
+
protected
|
87
|
+
|
88
|
+
# Splits the provided key into a prefix and the remaining part
|
89
|
+
#
|
90
|
+
# @param key [String] the key to be split
|
91
|
+
#
|
92
|
+
# @example Splitting a key
|
93
|
+
# split_key("prefix-key") #=> "acr/prefix/keyvalue"
|
94
|
+
#
|
95
|
+
# @return [Array<String>] an array containing two elements: the part before the first "-", and the rest of the string
|
96
|
+
def split_key(key)
|
97
|
+
# Prefix of keys are expected to be the first part of key separated by a dash.
|
98
|
+
prefix, k = key.split(ActiveCachedResource::Constants::PREFIX_SEPARATOR, 2)
|
99
|
+
[prefix, k]
|
100
|
+
end
|
101
|
+
|
79
102
|
private
|
80
103
|
|
81
104
|
# Generates a hashed key for caching purposes.
|
@@ -88,25 +111,25 @@ module ActiveCachedResource
|
|
88
111
|
# @example Hashing a key
|
89
112
|
# hash_key("prefix-key") #=> "acr/prefix/Digest::SHA256.hexdigest(key)"
|
90
113
|
#
|
114
|
+
# @raise [ArgumentError] If the key does not contain a prefix and a key separated by a dash.
|
115
|
+
#
|
91
116
|
# @param key [String] the original key to be hashed. It is expected to have a prefix and the key separated by a dash.
|
92
117
|
# @return [String] the generated hashed key with the global prefix and the prefix from the original key.
|
93
118
|
def hash_key(key)
|
94
|
-
|
95
|
-
prefix, k = key.split("-", 2)
|
119
|
+
prefix, k = split_key(key)
|
96
120
|
if prefix.nil? || k.nil?
|
97
121
|
raise ArgumentError, "Key must have a prefix and a key separated by a dash"
|
98
122
|
end
|
99
|
-
|
100
|
-
"#{prefix}/" + Digest::SHA256.hexdigest(k)
|
123
|
+
"#{prefix}#{ActiveCachedResource::Constants::PREFIX_SEPARATOR}#{Digest::SHA256.hexdigest(k)}"
|
101
124
|
end
|
102
125
|
|
103
126
|
def compress(value)
|
104
|
-
|
127
|
+
value.to_json
|
105
128
|
end
|
106
129
|
|
107
130
|
def decompress(value)
|
108
|
-
|
109
|
-
rescue
|
131
|
+
JSON.parse(value)
|
132
|
+
rescue JSON::ParserError
|
110
133
|
nil
|
111
134
|
end
|
112
135
|
end
|
@@ -7,7 +7,7 @@ module ActiveCachedResource
|
|
7
7
|
|
8
8
|
# Delete the reload param from query params.
|
9
9
|
# This is drilled down via `params` option to determine if the collection should be reloaded
|
10
|
-
should_reload = query_params.delete(
|
10
|
+
should_reload = query_params.delete(Constants::RELOAD_PARAM)
|
11
11
|
if !should_reload
|
12
12
|
from_cache = resource_class.send(:cache_read, from, path_params, query_params, prefix_options)
|
13
13
|
@elements = from_cache
|
@@ -21,6 +21,23 @@ module ActiveResource # :nodoc:
|
|
21
21
|
attr_writer :prefix_options
|
22
22
|
attr_reader :from
|
23
23
|
|
24
|
+
# Returns a frozen empty collection.
|
25
|
+
#
|
26
|
+
# @return [ActiveResource::Collection] an empty collection
|
27
|
+
def self.none
|
28
|
+
new([]).tap do |collection|
|
29
|
+
collection.instance_variable_set(:@requested, true)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Creates a new ActiveResource::Collection instance.
|
34
|
+
#
|
35
|
+
# ==== Arguments
|
36
|
+
#
|
37
|
+
# +elements+ (Array<Object>) - An optional array of resources to be set as the collection elements.
|
38
|
+
# Defaults to an empty array.
|
39
|
+
# +from+ (String, Symbol) - The path to the collection resource or the symbol for the collection resource.
|
40
|
+
|
24
41
|
# ActiveResource::Collection is a wrapper to handle parsing index responses that
|
25
42
|
# do not directly map to Rails conventions.
|
26
43
|
#
|
@@ -98,12 +115,12 @@ module ActiveResource # :nodoc:
|
|
98
115
|
@prefix_options || {}
|
99
116
|
end
|
100
117
|
|
101
|
-
#
|
118
|
+
# Reload the collection by re-fetching the resources from the API.
|
102
119
|
#
|
103
120
|
# ==== Returns
|
104
121
|
#
|
105
122
|
# [Array<Object>] The collection of resources retrieved from the API.
|
106
|
-
def
|
123
|
+
def reload
|
107
124
|
@requested = false
|
108
125
|
request_resources!
|
109
126
|
end
|
@@ -182,6 +199,7 @@ module ActiveResource # :nodoc:
|
|
182
199
|
# # => PostCollection:xxx (filtered collection)
|
183
200
|
def where(clauses = {})
|
184
201
|
raise ArgumentError, "expected a clauses Hash, got #{clauses.inspect}" unless clauses.is_a? Hash
|
202
|
+
return self.class.none if resource_class.nil?
|
185
203
|
new_clauses = query_params.merge(clauses)
|
186
204
|
resource_class.where(new_clauses)
|
187
205
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_cached_resource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Luis Urena
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-01-
|
10
|
+
date: 2025-01-23 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: activemodel-serializers-xml
|
@@ -52,25 +52,19 @@ dependencies:
|
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '6.0'
|
54
54
|
- !ruby/object:Gem::Dependency
|
55
|
-
name:
|
55
|
+
name: ostruct
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
61
|
-
- - ">="
|
62
|
-
- !ruby/object:Gem::Version
|
63
|
-
version: 1.7.5
|
60
|
+
version: 0.6.1
|
64
61
|
type: :runtime
|
65
62
|
prerelease: false
|
66
63
|
version_requirements: !ruby/object:Gem::Requirement
|
67
64
|
requirements:
|
68
65
|
- - "~>"
|
69
66
|
- !ruby/object:Gem::Version
|
70
|
-
version:
|
71
|
-
- - ">="
|
72
|
-
- !ruby/object:Gem::Version
|
73
|
-
version: 1.7.5
|
67
|
+
version: 0.6.1
|
74
68
|
email:
|
75
69
|
- eljean@live.com
|
76
70
|
executables: []
|
@@ -87,6 +81,7 @@ files:
|
|
87
81
|
- lib/active_cached_resource/caching_strategies/sql_cache.rb
|
88
82
|
- lib/active_cached_resource/collection.rb
|
89
83
|
- lib/active_cached_resource/configuration.rb
|
84
|
+
- lib/active_cached_resource/constants.rb
|
90
85
|
- lib/active_cached_resource/logger.rb
|
91
86
|
- lib/active_cached_resource/model.rb
|
92
87
|
- lib/active_cached_resource/version.rb
|
@@ -141,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
136
|
- !ruby/object:Gem::Version
|
142
137
|
version: '0'
|
143
138
|
requirements: []
|
144
|
-
rubygems_version: 3.6.
|
139
|
+
rubygems_version: 3.6.3
|
145
140
|
specification_version: 4
|
146
141
|
summary: ActiveResource, but with a caching layer.
|
147
142
|
test_files: []
|