flipper-active_support_cache_store 0.28.3 → 1.3.6

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: e829c5ac55bce11f8bd8f6861439d72ff43e30c40e1b2e34ac30b12411420781
4
- data.tar.gz: ac9e18f185f905a1332d596cd0c272a7199269b10ece0ee57a19d67b8a50fa3e
3
+ metadata.gz: a7b5c9414cd4c0a7af95ab90873d6830a19e4befda24d8f22b395f88a3fc63c5
4
+ data.tar.gz: b64460a641c23b702de19f27e7996643a5b8f2caf32aee9949369762c52ae6af
5
5
  SHA512:
6
- metadata.gz: a29e3142c493bd04435205a03486a1fd238dbe3699f3bace5fc0b95356e820c8cbcfea286eab3780a5957ea025d0a5f647c0e8b24768f775dac2da846dc9d09f
7
- data.tar.gz: 75108b097026d1b9c9f9043c26fdfaf531c4db22f386337052d3bcb7a8f4dcf06556eca5b8d84e1673c4f6cd19a523caff00971e2ce4d2ceefd998799842f97c
6
+ metadata.gz: fc8c1e1f151f8d40dfe64bea6627f9724e5ce65b091ffe2972378eacb6c29beb8a1984f408d6e2df3c550525361e318ddd924935ba548f9aaed1b2c54836b9ff
7
+ data.tar.gz: d032cce0605787fc4ff38cc4537088ef607d927b8d38826e9f0904f17141e460495e39b4f7351f1a27d2fe1c75e692fc844ef733541916d42beaed864ae7234a
@@ -8,10 +8,10 @@ end
8
8
 
9
9
  Gem::Specification.new do |gem|
10
10
  gem.authors = ['John Nunemaker']
11
- gem.email = ['nunemaker@gmail.com']
12
- gem.summary = 'ActiveSupport::Cache store adapter for Flipper'
11
+ gem.email = 'support@flippercloud.io'
12
+ gem.summary = 'ActiveSupport::Cache feature flag cache adapter for Flipper'
13
13
  gem.license = 'MIT'
14
- gem.homepage = 'https://github.com/jnunemaker/flipper'
14
+ gem.homepage = 'https://www.flippercloud.io/docs/optimization#activesupportcachestore'
15
15
 
16
16
  gem.files = `git ls-files`.split("\n").select(&flipper_active_support_cache_store_files) + ['lib/flipper/version.rb']
17
17
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n").select(&flipper_active_support_cache_store_files)
@@ -21,5 +21,5 @@ Gem::Specification.new do |gem|
21
21
  gem.metadata = Flipper::METADATA
22
22
 
23
23
  gem.add_dependency 'flipper', "~> #{Flipper::VERSION}"
24
- gem.add_dependency 'activesupport', '>= 4.2', '< 8'
24
+ gem.add_dependency 'activesupport', '>= 4.2', '< 9'
25
25
  end
@@ -1,155 +1,85 @@
1
1
  require 'flipper'
2
+ require 'flipper/adapters/cache_base'
2
3
  require 'active_support/notifications'
3
4
 
4
5
  module Flipper
5
6
  module Adapters
6
7
  # Public: Adapter that wraps another adapter with the ability to cache
7
8
  # adapter calls in ActiveSupport::ActiveSupportCacheStore caches.
8
- #
9
- class ActiveSupportCacheStore
10
- include ::Flipper::Adapter
9
+ class ActiveSupportCacheStore < CacheBase
11
10
 
12
- Version = 'v1'.freeze
13
- Namespace = "flipper/#{Version}".freeze
14
- FeaturesKey = "#{Namespace}/features".freeze
15
- GetAllKey = "#{Namespace}/get_all".freeze
11
+ # Public: The race_condition_ttl for all cached data.
12
+ attr_reader :race_condition_ttl
16
13
 
17
- # Private
18
- def self.key_for(key)
19
- "#{Namespace}/feature/#{key}"
20
- end
21
-
22
- # Internal
23
- attr_reader :cache
24
-
25
- # Public: The name of the adapter.
26
- attr_reader :name
27
-
28
- # Public
29
- def initialize(adapter, cache, expires_in: nil, write_through: false)
30
- @adapter = adapter
31
- @name = :active_support_cache_store
32
- @cache = cache
33
- @write_options = {}
34
- @write_options[:expires_in] = expires_in if expires_in
14
+ def initialize(adapter, cache, ttl = nil, expires_in: :none_provided, race_condition_ttl: nil, write_through: false, prefix: nil)
15
+ if expires_in == :none_provided
16
+ ttl ||= nil
17
+ else
18
+ warn "DEPRECATION WARNING: The `expires_in` kwarg is deprecated for " +
19
+ "Flipper::Adapters::ActiveSupportCacheStore and will be removed " +
20
+ "in the next major version. Please pass in expires in as third " +
21
+ "argument instead."
22
+ ttl = expires_in
23
+ end
24
+ super(adapter, cache, ttl, prefix: prefix)
25
+ @race_condition_ttl = race_condition_ttl
35
26
  @write_through = write_through
36
27
  end
37
28
 
38
- # Public
39
- def features
40
- read_feature_keys
41
- end
42
-
43
- # Public
44
- def add(feature)
45
- result = @adapter.add(feature)
46
- @cache.delete(FeaturesKey)
47
- result
48
- end
49
-
50
- ## Public
51
29
  def remove(feature)
52
- result = @adapter.remove(feature)
53
- @cache.delete(FeaturesKey)
54
-
55
30
  if @write_through
56
- @cache.write(key_for(feature.key), default_config, @write_options)
31
+ result = @adapter.remove(feature)
32
+ expire_features_cache
33
+ cache_write feature_cache_key(feature.key), default_config
34
+ result
57
35
  else
58
- @cache.delete(key_for(feature.key))
36
+ super
59
37
  end
60
-
61
- result
62
38
  end
63
39
 
64
- ## Public
65
- def clear(feature)
66
- result = @adapter.clear(feature)
67
- @cache.delete(key_for(feature.key))
68
- result
69
- end
70
-
71
- ## Public
72
- def get(feature)
73
- @cache.fetch(key_for(feature.key), @write_options) do
74
- @adapter.get(feature)
75
- end
76
- end
77
-
78
- def get_multi(features)
79
- read_many_features(features)
80
- end
81
-
82
- def get_all
83
- if @cache.write(GetAllKey, Time.now.to_i, @write_options.merge(unless_exist: true))
84
- response = @adapter.get_all
85
- response.each do |key, value|
86
- @cache.write(key_for(key), value, @write_options)
87
- end
88
- @cache.write(FeaturesKey, response.keys.to_set, @write_options)
89
- response
90
- else
91
- features = read_feature_keys.map { |key| Flipper::Feature.new(key, self) }
92
- read_many_features(features)
93
- end
94
- end
95
-
96
- ## Public
97
40
  def enable(feature, gate, thing)
98
- result = @adapter.enable(feature, gate, thing)
99
-
100
41
  if @write_through
101
- @cache.write(key_for(feature.key), @adapter.get(feature), @write_options)
42
+ result = @adapter.enable(feature, gate, thing)
43
+ cache_write feature_cache_key(feature.key), @adapter.get(feature)
44
+ result
102
45
  else
103
- @cache.delete(key_for(feature.key))
46
+ super
104
47
  end
105
-
106
- result
107
48
  end
108
49
 
109
- ## Public
110
50
  def disable(feature, gate, thing)
111
- result = @adapter.disable(feature, gate, thing)
112
-
113
51
  if @write_through
114
- @cache.write(key_for(feature.key), @adapter.get(feature), @write_options)
52
+ result = @adapter.disable(feature, gate, thing)
53
+ cache_write feature_cache_key(feature.key), @adapter.get(feature)
54
+ result
115
55
  else
116
- @cache.delete(key_for(feature.key))
56
+ super
117
57
  end
118
-
119
- result
120
58
  end
121
59
 
122
60
  private
123
61
 
124
- def key_for(key)
125
- self.class.key_for(key)
62
+ def cache_fetch(key, &block)
63
+ @cache.fetch(key, write_options, &block)
126
64
  end
127
65
 
128
- # Internal: Returns an array of the known feature keys.
129
- def read_feature_keys
130
- @cache.fetch(FeaturesKey, @write_options) { @adapter.features }
66
+ def cache_read_multi(keys)
67
+ @cache.read_multi(*keys)
131
68
  end
132
69
 
133
- # Internal: Given an array of features, attempts to read through cache in
134
- # as few network calls as possible.
135
- def read_many_features(features)
136
- keys = features.map { |feature| key_for(feature.key) }
137
- cache_result = @cache.read_multi(*keys)
138
- uncached_features = features.reject { |feature| cache_result[key_for(feature)] }
70
+ def cache_write(key, value)
71
+ @cache.write(key, value, write_options)
72
+ end
139
73
 
140
- if uncached_features.any?
141
- response = @adapter.get_multi(uncached_features)
142
- response.each do |key, value|
143
- @cache.write(key_for(key), value, @write_options)
144
- cache_result[key_for(key)] = value
145
- end
146
- end
74
+ def cache_delete(key)
75
+ @cache.delete(key)
76
+ end
147
77
 
148
- result = {}
149
- features.each do |feature|
150
- result[feature.key] = cache_result[key_for(feature.key)]
151
- end
152
- result
78
+ def write_options
79
+ write_options = {}
80
+ write_options[:expires_in] = @ttl if @ttl
81
+ write_options[:race_condition_ttl] if @race_condition_ttl
82
+ write_options
153
83
  end
154
84
  end
155
85
  end
@@ -1,3 +1,13 @@
1
1
  module Flipper
2
- VERSION = '0.28.3'.freeze
2
+ VERSION = '1.3.6'.freeze
3
+
4
+ REQUIRED_RUBY_VERSION = '2.6'.freeze
5
+ NEXT_REQUIRED_RUBY_VERSION = '3.0'.freeze
6
+
7
+ REQUIRED_RAILS_VERSION = '5.2'.freeze
8
+ NEXT_REQUIRED_RAILS_VERSION = '6.1.0'.freeze
9
+
10
+ def self.deprecated_ruby_version?
11
+ Gem::Version.new(RUBY_VERSION) < Gem::Version.new(NEXT_REQUIRED_RUBY_VERSION)
12
+ end
3
13
  end
@@ -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, expires_in: 10.seconds, 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 }
@@ -19,6 +20,101 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
19
20
 
20
21
  it_should_behave_like 'a flipper adapter'
21
22
 
23
+ it "knows ttl" do
24
+ expect(adapter.ttl).to eq(10)
25
+ end
26
+
27
+ it "knows ttl when only expires_in provided" do
28
+ silence do
29
+ adapter = described_class.new(memory_adapter, cache, expires_in: 10)
30
+ expect(adapter.ttl).to eq(10)
31
+ end
32
+ end
33
+
34
+ it "knows ttl when ttl and expires_in are provided" do
35
+ silence do
36
+ adapter = described_class.new(memory_adapter, cache, 200, expires_in: 10)
37
+ expect(adapter.ttl).to eq(10)
38
+ end
39
+ end
40
+
41
+ it "knows default when no ttl or expires_in provided" do
42
+ adapter = described_class.new(memory_adapter, cache)
43
+ expect(adapter.ttl).to be(nil)
44
+ end
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
+
55
+ it "knows features_cache_key" do
56
+ expect(adapter.features_cache_key).to eq("flipper/v1/features")
57
+ end
58
+
59
+ it "can expire features cache" do
60
+ # cache the features
61
+ adapter.features
62
+ expect(cache.read("flipper/v1/features")).not_to be(nil)
63
+
64
+ # expire cache
65
+ adapter.expire_features_cache
66
+ expect(cache.read("flipper/v1/features")).to be(nil)
67
+ end
68
+
69
+ it "can expire feature cache" do
70
+ # cache the features
71
+ adapter.get(flipper[:stats])
72
+ expect(cache.read("flipper/v1/feature/stats")).not_to be(nil)
73
+
74
+ # expire cache
75
+ adapter.expire_feature_cache("stats")
76
+ expect(cache.read("flipper/v1/feature/stats")).to be(nil)
77
+ end
78
+
79
+ it "can generate feature cache key" do
80
+ expect(adapter.feature_cache_key("stats")).to eq("flipper/v1/feature/stats")
81
+ end
82
+
83
+ context "when using a prefix" do
84
+ let(:adapter) { described_class.new(memory_adapter, cache, 10, prefix: "foo/") }
85
+ it_should_behave_like 'a flipper adapter'
86
+
87
+ it "knows features_cache_key" do
88
+ expect(adapter.features_cache_key).to eq("foo/flipper/v1/features")
89
+ end
90
+
91
+ it "can generate feature cache key" do
92
+ expect(adapter.feature_cache_key("stats")).to eq("foo/flipper/v1/feature/stats")
93
+ end
94
+
95
+ it "uses the prefix for all keys" do
96
+ # check individual feature get cached with prefix
97
+ adapter.get(flipper[:stats])
98
+ expect(cache.read("foo/flipper/v1/feature/stats")).not_to be(nil)
99
+
100
+ # check individual feature expired with prefix
101
+ adapter.remove(flipper[:stats])
102
+ expect(cache.read("foo/flipper/v1/feature/stats")).to be(nil)
103
+
104
+ # enable some stuff
105
+ flipper.enable_percentage_of_actors(:search, 10)
106
+ flipper.enable(:stats)
107
+
108
+ # populate the cache
109
+ adapter.get_all
110
+
111
+ # verify cached with prefix
112
+ expect(cache.read("foo/flipper/v1/features")).to eq(Set["stats", "search"])
113
+ expect(cache.read("foo/flipper/v1/feature/search")[:percentage_of_actors]).to eq("10")
114
+ expect(cache.read("foo/flipper/v1/feature/stats")[:boolean]).to eq("true")
115
+ end
116
+ end
117
+
22
118
  describe '#remove' do
23
119
  let(:feature) { flipper[:stats] }
24
120
 
@@ -28,8 +124,8 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
28
124
  end
29
125
 
30
126
  it 'expires feature and deletes the cache' do
31
- expect(cache.read(described_class.key_for(feature))).to be_nil
32
- expect(cache.exist?(described_class.key_for(feature))).to be(false)
127
+ expect(cache.read("flipper/v1/feature/#{feature.key}")).to be_nil
128
+ expect(cache.exist?("flipper/v1/feature/#{feature.key}")).to be(false)
33
129
  expect(feature).not_to be_enabled
34
130
  end
35
131
 
@@ -37,8 +133,8 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
37
133
  let(:write_through) { true }
38
134
 
39
135
  it 'expires feature and writes an empty value to the cache' do
40
- expect(cache.read(described_class.key_for(feature))).to eq(adapter.default_config)
41
- expect(cache.exist?(described_class.key_for(feature))).to be(true)
136
+ expect(cache.read("flipper/v1/feature/#{feature.key}")).to eq(adapter.default_config)
137
+ expect(cache.exist?("flipper/v1/feature/#{feature.key}")).to be(true)
42
138
  expect(feature).not_to be_enabled
43
139
  end
44
140
  end
@@ -48,12 +144,12 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
48
144
  let(:feature) { flipper[:stats] }
49
145
 
50
146
  before do
51
- adapter.enable(feature, feature.gate(:boolean), flipper.boolean)
147
+ adapter.enable(feature, feature.gate(:boolean), Flipper::Types::Boolean.new(true))
52
148
  end
53
149
 
54
150
  it 'enables feature and deletes the cache' do
55
- expect(cache.read(described_class.key_for(feature))).to be_nil
56
- expect(cache.exist?(described_class.key_for(feature))).to be(false)
151
+ expect(cache.read("flipper/v1/feature/#{feature.key}")).to be_nil
152
+ expect(cache.exist?("flipper/v1/feature/#{feature.key}")).to be(false)
57
153
  expect(feature).to be_enabled
58
154
  end
59
155
 
@@ -61,8 +157,8 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
61
157
  let(:write_through) { true }
62
158
 
63
159
  it 'expires feature and writes to the cache' do
64
- expect(cache.exist?(described_class.key_for(feature))).to be(true)
65
- expect(cache.read(described_class.key_for(feature))).to include(boolean: 'true')
160
+ expect(cache.exist?("flipper/v1/feature/#{feature.key}")).to be(true)
161
+ expect(cache.read("flipper/v1/feature/#{feature.key}")).to include(boolean: 'true')
66
162
  expect(feature).to be_enabled
67
163
  end
68
164
  end
@@ -72,12 +168,12 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
72
168
  let(:feature) { flipper[:stats] }
73
169
 
74
170
  before do
75
- adapter.disable(feature, feature.gate(:boolean), flipper.boolean)
171
+ adapter.disable(feature, feature.gate(:boolean), Flipper::Types::Boolean.new)
76
172
  end
77
173
 
78
174
  it 'disables feature and deletes the cache' do
79
- expect(cache.read(described_class.key_for(feature))).to be_nil
80
- expect(cache.exist?(described_class.key_for(feature))).to be(false)
175
+ expect(cache.read("flipper/v1/feature/#{feature.key}")).to be_nil
176
+ expect(cache.exist?("flipper/v1/feature/#{feature.key}")).to be(false)
81
177
  expect(feature).not_to be_enabled
82
178
  end
83
179
 
@@ -85,8 +181,8 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
85
181
  let(:write_through) { true }
86
182
 
87
183
  it 'expires feature and writes to the cache' do
88
- expect(cache.exist?(described_class.key_for(feature))).to be(true)
89
- expect(cache.read(described_class.key_for(feature))).to include(boolean: nil)
184
+ expect(cache.exist?("flipper/v1/feature/#{feature.key}")).to be(true)
185
+ expect(cache.read("flipper/v1/feature/#{feature.key}")).to include(boolean: nil)
90
186
  expect(feature).not_to be_enabled
91
187
  end
92
188
  end
@@ -103,13 +199,13 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
103
199
  memory_adapter.reset
104
200
 
105
201
  adapter.get(stats)
106
- expect(cache.read(described_class.key_for(search))).to be(nil)
107
- expect(cache.read(described_class.key_for(other))).to be(nil)
202
+ expect(cache.read("flipper/v1/feature/#{search.key}")).to be(nil)
203
+ expect(cache.read("flipper/v1/feature/#{other.key}")).to be(nil)
108
204
 
109
205
  adapter.get_multi([stats, search, other])
110
206
 
111
- expect(cache.read(described_class.key_for(search))[:boolean]).to eq('true')
112
- expect(cache.read(described_class.key_for(other))[:boolean]).to be(nil)
207
+ expect(cache.read("flipper/v1/feature/#{search.key}")[:boolean]).to eq('true')
208
+ expect(cache.read("flipper/v1/feature/#{other.key}")[:boolean]).to be(nil)
113
209
 
114
210
  adapter.get_multi([stats, search, other])
115
211
  adapter.get_multi([stats, search, other])
@@ -128,19 +224,21 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
128
224
 
129
225
  it 'warms all features' do
130
226
  adapter.get_all
131
- expect(cache.read(described_class.key_for(stats))[:boolean]).to eq('true')
132
- expect(cache.read(described_class.key_for(search))[:boolean]).to be(nil)
133
- expect(cache.read(described_class::GetAllKey)).to be_within(2).of(Time.now.to_i)
227
+ expect(cache.read("flipper/v1/feature/#{stats.key}")[:boolean]).to eq('true')
228
+ expect(cache.read("flipper/v1/feature/#{search.key}")[:boolean]).to be(nil)
229
+ expect(cache.read("flipper/v1/features")).to eq(Set["stats", "search"])
134
230
  end
135
231
 
136
232
  it 'returns same result when already cached' do
137
233
  expect(adapter.get_all).to eq(adapter.get_all)
138
234
  end
139
235
 
140
- it 'only invokes one call to wrapped adapter' do
236
+ it 'only invokes two calls to wrapped adapter (for features set and gate data for each feature in set)' do
141
237
  memory_adapter.reset
142
238
  5.times { adapter.get_all }
143
- expect(memory_adapter.count(:get_all)).to eq(1)
239
+ expect(memory_adapter.count(:features)).to eq(1)
240
+ expect(memory_adapter.count(:get_multi)).to eq(1)
241
+ expect(memory_adapter.count).to eq(2)
144
242
  end
145
243
  end
146
244
 
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper-active_support_cache_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.28.3
4
+ version: 1.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-07-21 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: flipper
@@ -16,14 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - "~>"
18
17
  - !ruby/object:Gem::Version
19
- version: 0.28.3
18
+ version: 1.3.6
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
- version: 0.28.3
25
+ version: 1.3.6
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: activesupport
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -33,7 +32,7 @@ dependencies:
33
32
  version: '4.2'
34
33
  - - "<"
35
34
  - !ruby/object:Gem::Version
36
- version: '8'
35
+ version: '9'
37
36
  type: :runtime
38
37
  prerelease: false
39
38
  version_requirements: !ruby/object:Gem::Requirement
@@ -43,10 +42,8 @@ dependencies:
43
42
  version: '4.2'
44
43
  - - "<"
45
44
  - !ruby/object:Gem::Version
46
- version: '8'
47
- description:
48
- email:
49
- - nunemaker@gmail.com
45
+ version: '9'
46
+ email: support@flippercloud.io
50
47
  executables: []
51
48
  extensions: []
52
49
  extra_rdoc_files: []
@@ -56,12 +53,16 @@ files:
56
53
  - lib/flipper/adapters/active_support_cache_store.rb
57
54
  - lib/flipper/version.rb
58
55
  - spec/flipper/adapters/active_support_cache_store_spec.rb
59
- homepage: https://github.com/jnunemaker/flipper
56
+ homepage: https://www.flippercloud.io/docs/optimization#activesupportcachestore
60
57
  licenses:
61
58
  - MIT
62
59
  metadata:
63
- changelog_uri: https://github.com/jnunemaker/flipper/blob/main/Changelog.md
64
- post_install_message:
60
+ documentation_uri: https://www.flippercloud.io/docs
61
+ homepage_uri: https://www.flippercloud.io
62
+ source_code_uri: https://github.com/flippercloud/flipper
63
+ bug_tracker_uri: https://github.com/flippercloud/flipper/issues
64
+ changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.3.6
65
+ funding_uri: https://github.com/sponsors/flippercloud
65
66
  rdoc_options: []
66
67
  require_paths:
67
68
  - lib
@@ -76,9 +77,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
77
  - !ruby/object:Gem::Version
77
78
  version: '0'
78
79
  requirements: []
79
- rubygems_version: 3.3.7
80
- signing_key:
80
+ rubygems_version: 3.6.9
81
81
  specification_version: 4
82
- summary: ActiveSupport::Cache store adapter for Flipper
82
+ summary: ActiveSupport::Cache feature flag cache adapter for Flipper
83
83
  test_files:
84
84
  - spec/flipper/adapters/active_support_cache_store_spec.rb