flipper-active_support_cache_store 1.3.5 → 1.4.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: 356c52f80f850af9e58db4ffb2fc51975e10480ed7fa8ab1a1aa6a7841259fae
4
- data.tar.gz: d371916168473712352d6741495c4d4b2a13c64ec950bd4cfe84085eb3fc9497
3
+ metadata.gz: f24ef2d4b542a165ec1c70ec7e52c28f7fd666f3a8c5b7c58ddd79d1cbedaad7
4
+ data.tar.gz: d7aa239fa34e287564fadded1ecd86e502f9a2efa6f6e76620838ddfda6f93c7
5
5
  SHA512:
6
- metadata.gz: e9a31f234074b60d3af10c5c56d38e7c5c435e994cb713aed8b3db0045424461b61684598d814e46ab5f48c0992da1c43ead88bb9eb062fdb683d315911b8e4d
7
- data.tar.gz: 9f0952d9b947c523c0c9e4b1fc1c2ceecb09951aa63948b0b73aa8eef9856690bcca5b878841c211515593b74b91b2e54550322387dc65f1846cebcfb2a90abf
6
+ metadata.gz: e5c6170f5a3cfc6d2bf352aa68cdb43088a9a18189ce63b196493367e24e029c16c6636bc5c896c01070587762333073f27240411a692c05f16dfc8de894ede9
7
+ data.tar.gz: 0f24fa65c8075ad1f66abc716f0c82490869e91a81dff0840778b7647812e4e7df621784720aff8534734dc0343f39f81df2f055b28d1e081d98070cb0daf969
@@ -7,7 +7,11 @@ module Flipper
7
7
  # Public: Adapter that wraps another adapter with the ability to cache
8
8
  # adapter calls in ActiveSupport::ActiveSupportCacheStore caches.
9
9
  class ActiveSupportCacheStore < CacheBase
10
- def initialize(adapter, cache, ttl = nil, expires_in: :none_provided, write_through: false, prefix: nil)
10
+
11
+ # Public: The race_condition_ttl for all cached data.
12
+ attr_reader :race_condition_ttl
13
+
14
+ def initialize(adapter, cache, ttl = nil, expires_in: :none_provided, race_condition_ttl: nil, write_through: false, prefix: nil)
11
15
  if expires_in == :none_provided
12
16
  ttl ||= nil
13
17
  else
@@ -18,6 +22,7 @@ module Flipper
18
22
  ttl = expires_in
19
23
  end
20
24
  super(adapter, cache, ttl, prefix: prefix)
25
+ @race_condition_ttl = race_condition_ttl
21
26
  @write_through = write_through
22
27
  end
23
28
 
@@ -36,6 +41,7 @@ module Flipper
36
41
  if @write_through
37
42
  result = @adapter.enable(feature, gate, thing)
38
43
  cache_write feature_cache_key(feature.key), @adapter.get(feature)
44
+ expire_get_all_cache
39
45
  result
40
46
  else
41
47
  super
@@ -46,6 +52,7 @@ module Flipper
46
52
  if @write_through
47
53
  result = @adapter.disable(feature, gate, thing)
48
54
  cache_write feature_cache_key(feature.key), @adapter.get(feature)
55
+ expire_get_all_cache
49
56
  result
50
57
  else
51
58
  super
@@ -73,6 +80,7 @@ module Flipper
73
80
  def write_options
74
81
  write_options = {}
75
82
  write_options[:expires_in] = @ttl if @ttl
83
+ write_options[:race_condition_ttl] if @race_condition_ttl
76
84
  write_options
77
85
  end
78
86
  end
@@ -1,5 +1,5 @@
1
1
  module Flipper
2
- VERSION = '1.3.5'.freeze
2
+ VERSION = '1.4.0'.freeze
3
3
 
4
4
  REQUIRED_RUBY_VERSION = '2.6'.freeze
5
5
  NEXT_REQUIRED_RUBY_VERSION = '3.0'.freeze
@@ -8,7 +8,8 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
8
8
  end
9
9
  let(:cache) { ActiveSupport::Cache::MemoryStore.new }
10
10
  let(:write_through) { false }
11
- let(:adapter) { described_class.new(memory_adapter, cache, 10, write_through: write_through) }
11
+ let(:race_condition_ttl) { 5 }
12
+ let(:adapter) { described_class.new(memory_adapter, cache, 10, race_condition_ttl: race_condition_ttl, write_through: write_through) }
12
13
  let(:flipper) { Flipper.new(adapter) }
13
14
 
14
15
  subject { adapter }
@@ -42,6 +43,15 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
42
43
  expect(adapter.ttl).to be(nil)
43
44
  end
44
45
 
46
+ it "knows race_condition_ttl" do
47
+ expect(adapter.race_condition_ttl).to eq(race_condition_ttl)
48
+ end
49
+
50
+ it "knows default when no ttl or expires_in provided" do
51
+ adapter = described_class.new(memory_adapter, cache)
52
+ expect(adapter.race_condition_ttl).to be(nil)
53
+ end
54
+
45
55
  it "knows features_cache_key" do
46
56
  expect(adapter.features_cache_key).to eq("flipper/v1/features")
47
57
  end
@@ -51,9 +61,13 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
51
61
  adapter.features
52
62
  expect(cache.read("flipper/v1/features")).not_to be(nil)
53
63
 
64
+ adapter.get_all
65
+ expect(cache.read("flipper/v1/get_all")).not_to be(nil)
66
+
54
67
  # expire cache
55
68
  adapter.expire_features_cache
56
69
  expect(cache.read("flipper/v1/features")).to be(nil)
70
+ expect(cache.read("flipper/v1/get_all")).to be(nil)
57
71
  end
58
72
 
59
73
  it "can expire feature cache" do
@@ -61,9 +75,13 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
61
75
  adapter.get(flipper[:stats])
62
76
  expect(cache.read("flipper/v1/feature/stats")).not_to be(nil)
63
77
 
78
+ adapter.get_all
79
+ expect(cache.read("flipper/v1/get_all")).not_to be(nil)
80
+
64
81
  # expire cache
65
82
  adapter.expire_feature_cache("stats")
66
83
  expect(cache.read("flipper/v1/feature/stats")).to be(nil)
84
+ expect(cache.read("flipper/v1/get_all")).to be(nil)
67
85
  end
68
86
 
69
87
  it "can generate feature cache key" do
@@ -78,6 +96,10 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
78
96
  expect(adapter.features_cache_key).to eq("foo/flipper/v1/features")
79
97
  end
80
98
 
99
+ it "knows get_all_cache_key" do
100
+ expect(adapter.get_all_cache_key).to eq("foo/flipper/v1/get_all")
101
+ end
102
+
81
103
  it "can generate feature cache key" do
82
104
  expect(adapter.feature_cache_key("stats")).to eq("foo/flipper/v1/feature/stats")
83
105
  end
@@ -99,9 +121,10 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
99
121
  adapter.get_all
100
122
 
101
123
  # verify cached with prefix
124
+ get_all_cache_value = cache.read("foo/flipper/v1/get_all")
102
125
  expect(cache.read("foo/flipper/v1/features")).to eq(Set["stats", "search"])
103
- expect(cache.read("foo/flipper/v1/feature/search")[:percentage_of_actors]).to eq("10")
104
- expect(cache.read("foo/flipper/v1/feature/stats")[:boolean]).to eq("true")
126
+ expect(get_all_cache_value["search"][:percentage_of_actors]).to eq("10")
127
+ expect(get_all_cache_value["stats"][:boolean]).to eq("true")
105
128
  end
106
129
  end
107
130
 
@@ -110,11 +133,13 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
110
133
 
111
134
  before do
112
135
  adapter.get(feature)
136
+ adapter.get_all
113
137
  adapter.remove(feature)
114
138
  end
115
139
 
116
140
  it 'expires feature and deletes the cache' do
117
141
  expect(cache.read("flipper/v1/feature/#{feature.key}")).to be_nil
142
+ expect(cache.read("flipper/v1/get_all")).to be(nil)
118
143
  expect(cache.exist?("flipper/v1/feature/#{feature.key}")).to be(false)
119
144
  expect(feature).not_to be_enabled
120
145
  end
@@ -134,10 +159,13 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
134
159
  let(:feature) { flipper[:stats] }
135
160
 
136
161
  before do
162
+ adapter.get(feature)
163
+ adapter.get_all
137
164
  adapter.enable(feature, feature.gate(:boolean), Flipper::Types::Boolean.new(true))
138
165
  end
139
166
 
140
167
  it 'enables feature and deletes the cache' do
168
+ expect(cache.read("flipper/v1/get_all")).to be(nil)
141
169
  expect(cache.read("flipper/v1/feature/#{feature.key}")).to be_nil
142
170
  expect(cache.exist?("flipper/v1/feature/#{feature.key}")).to be(false)
143
171
  expect(feature).to be_enabled
@@ -147,6 +175,7 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
147
175
  let(:write_through) { true }
148
176
 
149
177
  it 'expires feature and writes to the cache' do
178
+ expect(cache.read("flipper/v1/get_all")).to be(nil)
150
179
  expect(cache.exist?("flipper/v1/feature/#{feature.key}")).to be(true)
151
180
  expect(cache.read("flipper/v1/feature/#{feature.key}")).to include(boolean: 'true')
152
181
  expect(feature).to be_enabled
@@ -158,10 +187,13 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
158
187
  let(:feature) { flipper[:stats] }
159
188
 
160
189
  before do
190
+ adapter.get(feature)
191
+ adapter.get_all
161
192
  adapter.disable(feature, feature.gate(:boolean), Flipper::Types::Boolean.new)
162
193
  end
163
194
 
164
195
  it 'disables feature and deletes the cache' do
196
+ expect(cache.read("flipper/v1/get_all")).to be(nil)
165
197
  expect(cache.read("flipper/v1/feature/#{feature.key}")).to be_nil
166
198
  expect(cache.exist?("flipper/v1/feature/#{feature.key}")).to be(false)
167
199
  expect(feature).not_to be_enabled
@@ -214,8 +246,10 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
214
246
 
215
247
  it 'warms all features' do
216
248
  adapter.get_all
217
- expect(cache.read("flipper/v1/feature/#{stats.key}")[:boolean]).to eq('true')
218
- expect(cache.read("flipper/v1/feature/#{search.key}")[:boolean]).to be(nil)
249
+ get_all_cache_value = cache.read("flipper/v1/get_all")
250
+ expect(get_all_cache_value).not_to be(nil)
251
+ expect(get_all_cache_value["stats"][:boolean]).to eq('true')
252
+ expect(get_all_cache_value["search"][:boolean]).to be(nil)
219
253
  expect(cache.read("flipper/v1/features")).to eq(Set["stats", "search"])
220
254
  end
221
255
 
@@ -226,9 +260,8 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
226
260
  it 'only invokes two calls to wrapped adapter (for features set and gate data for each feature in set)' do
227
261
  memory_adapter.reset
228
262
  5.times { adapter.get_all }
229
- expect(memory_adapter.count(:features)).to eq(1)
230
- expect(memory_adapter.count(:get_multi)).to eq(1)
231
- expect(memory_adapter.count).to eq(2)
263
+ expect(memory_adapter.count(:get_all)).to eq(1)
264
+ expect(memory_adapter.count).to eq(1)
232
265
  end
233
266
  end
234
267
 
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper-active_support_cache_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.5
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-02-26 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: flipper
@@ -15,14 +16,14 @@ dependencies:
15
16
  requirements:
16
17
  - - "~>"
17
18
  - !ruby/object:Gem::Version
18
- version: 1.3.5
19
+ version: 1.4.0
19
20
  type: :runtime
20
21
  prerelease: false
21
22
  version_requirements: !ruby/object:Gem::Requirement
22
23
  requirements:
23
24
  - - "~>"
24
25
  - !ruby/object:Gem::Version
25
- version: 1.3.5
26
+ version: 1.4.0
26
27
  - !ruby/object:Gem::Dependency
27
28
  name: activesupport
28
29
  requirement: !ruby/object:Gem::Requirement
@@ -43,6 +44,7 @@ dependencies:
43
44
  - - "<"
44
45
  - !ruby/object:Gem::Version
45
46
  version: '9'
47
+ description:
46
48
  email: support@flippercloud.io
47
49
  executables: []
48
50
  extensions: []
@@ -61,8 +63,9 @@ metadata:
61
63
  homepage_uri: https://www.flippercloud.io
62
64
  source_code_uri: https://github.com/flippercloud/flipper
63
65
  bug_tracker_uri: https://github.com/flippercloud/flipper/issues
64
- changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.3.5
66
+ changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.4.0
65
67
  funding_uri: https://github.com/sponsors/flippercloud
68
+ post_install_message:
66
69
  rdoc_options: []
67
70
  require_paths:
68
71
  - lib
@@ -77,8 +80,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
80
  - !ruby/object:Gem::Version
78
81
  version: '0'
79
82
  requirements: []
80
- rubygems_version: 3.6.9
83
+ rubygems_version: 3.5.22
84
+ signing_key:
81
85
  specification_version: 4
82
86
  summary: ActiveSupport::Cache feature flag cache adapter for Flipper
83
- test_files:
84
- - spec/flipper/adapters/active_support_cache_store_spec.rb
87
+ test_files: []