flipper-redis 1.3.2 → 1.3.3
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/lib/flipper/adapters/redis.rb +33 -22
- data/lib/flipper/adapters/redis_cache.rb +8 -4
- data/lib/flipper/adapters/redis_shared/methods.rb +9 -0
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/adapters/redis_cache_spec.rb +1 -3
- data/spec/flipper/adapters/redis_spec.rb +78 -32
- metadata +8 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a790000c8a290b42d4e92173ddc5e00632c7113b16ca47c4c257d26ee36005aa
|
4
|
+
data.tar.gz: 6e6b7c2d513a8472e6bdc7cb99dff07daaf984751d7c7880bde92622663f95dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae7bf6f058f1a54ef97bbc2b3e86e03398d01c65df8f9752c5b0351d476e70d91754680df9223b15162c0dbd9c8cdfeb7ce5f4d40da6c6443915a2c8cecaf777
|
7
|
+
data.tar.gz: 709339de3e5a6cb919a2ae8fbf63f882f16fc06b7339b4fe171aef7d70feb4961031af6269b6fede7877a0bd5d1b96962b3025cc2bd4285ea6abe87ee0d59cc4
|
@@ -1,11 +1,13 @@
|
|
1
1
|
require 'set'
|
2
2
|
require 'redis'
|
3
3
|
require 'flipper'
|
4
|
+
require 'flipper/adapters/redis_shared/methods'
|
4
5
|
|
5
6
|
module Flipper
|
6
7
|
module Adapters
|
7
8
|
class Redis
|
8
9
|
include ::Flipper::Adapter
|
10
|
+
include ::Flipper::Adapters::RedisShared
|
9
11
|
|
10
12
|
attr_reader :key_prefix
|
11
13
|
|
@@ -25,6 +27,9 @@ module Flipper
|
|
25
27
|
def initialize(client, key_prefix: nil)
|
26
28
|
@client = client
|
27
29
|
@key_prefix = key_prefix
|
30
|
+
@sadd_returns_boolean = with_connection do |conn|
|
31
|
+
conn.class.respond_to?(:sadd_returns_boolean) && conn.class.sadd_returns_boolean
|
32
|
+
end
|
28
33
|
end
|
29
34
|
|
30
35
|
# Public: The set of known features.
|
@@ -35,9 +40,9 @@ module Flipper
|
|
35
40
|
# Public: Adds a feature to the set of known features.
|
36
41
|
def add(feature)
|
37
42
|
if redis_sadd_returns_boolean?
|
38
|
-
|
43
|
+
with_connection { |conn| conn.sadd? features_key, feature.key }
|
39
44
|
else
|
40
|
-
|
45
|
+
with_connection { |conn| conn.sadd features_key, feature.key }
|
41
46
|
end
|
42
47
|
true
|
43
48
|
end
|
@@ -45,17 +50,17 @@ module Flipper
|
|
45
50
|
# Public: Removes a feature from the set of known features.
|
46
51
|
def remove(feature)
|
47
52
|
if redis_sadd_returns_boolean?
|
48
|
-
|
53
|
+
with_connection { |conn| conn.srem? features_key, feature.key }
|
49
54
|
else
|
50
|
-
|
55
|
+
with_connection { |conn| conn.srem features_key, feature.key }
|
51
56
|
end
|
52
|
-
|
57
|
+
with_connection { |conn| conn.del key_for(feature.key) }
|
53
58
|
true
|
54
59
|
end
|
55
60
|
|
56
61
|
# Public: Clears the gate values for a feature.
|
57
62
|
def clear(feature)
|
58
|
-
|
63
|
+
with_connection { |conn| conn.del key_for(feature.key) }
|
59
64
|
true
|
60
65
|
end
|
61
66
|
|
@@ -88,13 +93,13 @@ module Flipper
|
|
88
93
|
case gate.data_type
|
89
94
|
when :boolean
|
90
95
|
clear(feature)
|
91
|
-
|
96
|
+
with_connection { |conn| conn.hset feature_key, gate.key, thing.value.to_s }
|
92
97
|
when :integer
|
93
|
-
|
98
|
+
with_connection { |conn| conn.hset feature_key, gate.key, thing.value.to_s }
|
94
99
|
when :set
|
95
|
-
|
100
|
+
with_connection { |conn| conn.hset feature_key, to_field(gate, thing), 1 }
|
96
101
|
when :json
|
97
|
-
|
102
|
+
with_connection { |conn| conn.hset feature_key, gate.key, Typecast.to_json(thing.value) }
|
98
103
|
else
|
99
104
|
unsupported_data_type gate.data_type
|
100
105
|
end
|
@@ -113,13 +118,13 @@ module Flipper
|
|
113
118
|
feature_key = key_for(feature.key)
|
114
119
|
case gate.data_type
|
115
120
|
when :boolean
|
116
|
-
|
121
|
+
with_connection { |conn| conn.del feature_key }
|
117
122
|
when :integer
|
118
|
-
|
123
|
+
with_connection { |conn| conn.hset feature_key, gate.key, thing.value.to_s }
|
119
124
|
when :set
|
120
|
-
|
125
|
+
with_connection { |conn| conn.hdel feature_key, to_field(gate, thing) }
|
121
126
|
when :json
|
122
|
-
|
127
|
+
with_connection { |conn| conn.hdel feature_key, gate.key }
|
123
128
|
else
|
124
129
|
unsupported_data_type gate.data_type
|
125
130
|
end
|
@@ -130,7 +135,7 @@ module Flipper
|
|
130
135
|
private
|
131
136
|
|
132
137
|
def redis_sadd_returns_boolean?
|
133
|
-
@
|
138
|
+
@sadd_returns_boolean
|
134
139
|
end
|
135
140
|
|
136
141
|
def read_many_features(features)
|
@@ -143,20 +148,26 @@ module Flipper
|
|
143
148
|
end
|
144
149
|
|
145
150
|
def read_feature_keys
|
146
|
-
|
151
|
+
with_connection { |conn| conn.smembers(features_key).to_set }
|
147
152
|
end
|
148
153
|
|
149
154
|
# Private: Gets a hash of fields => values for the given feature.
|
150
155
|
#
|
151
156
|
# Returns a Hash of fields => values.
|
152
|
-
def doc_for(feature, pipeline:
|
153
|
-
pipeline
|
157
|
+
def doc_for(feature, pipeline: nil)
|
158
|
+
if pipeline
|
159
|
+
pipeline.hgetall(key_for(feature.key))
|
160
|
+
else
|
161
|
+
with_connection { |conn| conn.hgetall(key_for(feature.key)) }
|
162
|
+
end
|
154
163
|
end
|
155
164
|
|
156
165
|
def docs_for(features)
|
157
|
-
|
158
|
-
|
159
|
-
|
166
|
+
with_connection do |conn|
|
167
|
+
conn.pipelined do |pipeline|
|
168
|
+
features.each do |feature|
|
169
|
+
doc_for(feature, pipeline: pipeline)
|
170
|
+
end
|
160
171
|
end
|
161
172
|
end
|
162
173
|
end
|
@@ -208,7 +219,7 @@ end
|
|
208
219
|
|
209
220
|
Flipper.configure do |config|
|
210
221
|
config.adapter do
|
211
|
-
client = Redis.new(url: ENV["FLIPPER_REDIS_URL"] || ENV["REDIS_URL"])
|
222
|
+
client = Redis.new(url: ENV["FLIPPER_REDIS_URL"] || ENV["REDIS_URL"] || "redis://localhost:6379")
|
212
223
|
Flipper::Adapters::Redis.new(client)
|
213
224
|
end
|
214
225
|
end
|
@@ -1,20 +1,24 @@
|
|
1
1
|
require 'redis'
|
2
2
|
require 'flipper'
|
3
3
|
require 'flipper/adapters/cache_base'
|
4
|
+
require 'flipper/adapters/redis_shared/methods'
|
4
5
|
|
5
6
|
module Flipper
|
6
7
|
module Adapters
|
7
8
|
# Public: Adapter that wraps another adapter with the ability to cache
|
8
9
|
# adapter calls in Redis.
|
9
10
|
class RedisCache < CacheBase
|
11
|
+
include ::Flipper::Adapters::RedisShared
|
12
|
+
|
10
13
|
def initialize(adapter, cache, ttl = 3600, prefix: nil)
|
14
|
+
@client = cache
|
11
15
|
super
|
12
16
|
end
|
13
17
|
|
14
18
|
private
|
15
19
|
|
16
20
|
def cache_fetch(key, &block)
|
17
|
-
cached =
|
21
|
+
cached = with_connection { |conn| conn.get(key) }
|
18
22
|
if cached
|
19
23
|
Marshal.load(cached)
|
20
24
|
else
|
@@ -27,7 +31,7 @@ module Flipper
|
|
27
31
|
def cache_read_multi(keys)
|
28
32
|
return {} if keys.empty?
|
29
33
|
|
30
|
-
values =
|
34
|
+
values = with_connection { |conn| conn.mget(*keys) }.map do |value|
|
31
35
|
value ? Marshal.load(value) : nil
|
32
36
|
end
|
33
37
|
|
@@ -35,11 +39,11 @@ module Flipper
|
|
35
39
|
end
|
36
40
|
|
37
41
|
def cache_write(key, value)
|
38
|
-
|
42
|
+
with_connection { |conn| conn.setex(key, @ttl, Marshal.dump(value)) }
|
39
43
|
end
|
40
44
|
|
41
45
|
def cache_delete(key)
|
42
|
-
|
46
|
+
with_connection { |conn| conn.del(key) }
|
43
47
|
end
|
44
48
|
end
|
45
49
|
end
|
data/lib/flipper/version.rb
CHANGED
@@ -3,9 +3,7 @@ require 'flipper/adapters/redis_cache'
|
|
3
3
|
|
4
4
|
RSpec.describe Flipper::Adapters::RedisCache do
|
5
5
|
let(:client) do
|
6
|
-
|
7
|
-
options[:url] = ENV['REDIS_URL'] if ENV['REDIS_URL']
|
8
|
-
Redis.new(options)
|
6
|
+
Redis.new(url: ENV.fetch('REDIS_URL', 'redis://localhost:6379'))
|
9
7
|
end
|
10
8
|
|
11
9
|
let(:memory_adapter) do
|
@@ -1,55 +1,101 @@
|
|
1
1
|
require 'flipper/adapters/redis'
|
2
|
+
require 'connection_pool'
|
2
3
|
|
3
4
|
RSpec.describe Flipper::Adapters::Redis do
|
4
|
-
|
5
|
-
|
5
|
+
context "redis instance" do
|
6
|
+
let(:client) do
|
7
|
+
Redis.raise_deprecations = true
|
8
|
+
Redis.new(url: ENV.fetch('REDIS_URL', 'redis://localhost:6379'))
|
9
|
+
end
|
6
10
|
|
7
|
-
|
11
|
+
subject { described_class.new(client) }
|
8
12
|
|
9
|
-
|
10
|
-
|
11
|
-
|
13
|
+
before do
|
14
|
+
skip_on_error(Redis::CannotConnectError, 'Redis not available') do
|
15
|
+
client.flushdb
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it_should_behave_like 'a flipper adapter'
|
12
20
|
|
13
|
-
|
21
|
+
it 'configures itself on load' do
|
22
|
+
Flipper.configuration = nil
|
23
|
+
Flipper.instance = nil
|
14
24
|
|
15
|
-
|
16
|
-
|
17
|
-
|
25
|
+
silence { load 'flipper/adapters/redis.rb' }
|
26
|
+
|
27
|
+
expect(Flipper.adapter.adapter).to be_a(Flipper::Adapters::Redis)
|
18
28
|
end
|
19
|
-
end
|
20
29
|
|
21
|
-
|
30
|
+
describe 'with a key_prefix' do
|
31
|
+
let(:subject) { described_class.new(client, key_prefix: "lockbox:") }
|
32
|
+
let(:feature) { Flipper::Feature.new(:search, subject) }
|
33
|
+
|
34
|
+
it_should_behave_like 'a flipper adapter'
|
35
|
+
|
36
|
+
it 'namespaces feature-keys' do
|
37
|
+
subject.add(feature)
|
22
38
|
|
23
|
-
|
24
|
-
|
25
|
-
|
39
|
+
expect(client.smembers("flipper_features")).to eq([])
|
40
|
+
expect(client.exists?("search")).to eq(false)
|
41
|
+
expect(client.smembers("lockbox:flipper_features")).to eq(["search"])
|
42
|
+
expect(client.hgetall("lockbox:search")).not_to eq(nil)
|
43
|
+
end
|
26
44
|
|
27
|
-
|
45
|
+
it "can remove namespaced keys" do
|
46
|
+
subject.add(feature)
|
47
|
+
expect(client.smembers("lockbox:flipper_features")).to eq(["search"])
|
28
48
|
|
29
|
-
|
49
|
+
subject.remove(feature)
|
50
|
+
expect(client.smembers("lockbox:flipper_features")).to be_empty
|
51
|
+
end
|
52
|
+
end
|
30
53
|
end
|
31
54
|
|
32
|
-
|
33
|
-
let(:
|
34
|
-
|
55
|
+
context "with a connection pool instance" do
|
56
|
+
let(:client) do
|
57
|
+
Redis.raise_deprecations = true
|
58
|
+
ConnectionPool.new(size: 1, timeout: 1) {
|
59
|
+
Redis.new(url: ENV.fetch('REDIS_URL', 'redis://localhost:6379'))
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
subject { described_class.new(client) }
|
64
|
+
|
65
|
+
before do
|
66
|
+
skip_on_error(Redis::CannotConnectError, 'Redis not available') do
|
67
|
+
client.with { |conn| conn.flushdb }
|
68
|
+
end
|
69
|
+
end
|
35
70
|
|
36
71
|
it_should_behave_like 'a flipper adapter'
|
37
72
|
|
38
|
-
|
39
|
-
subject.
|
73
|
+
describe 'with a key_prefix' do
|
74
|
+
let(:subject) { described_class.new(client, key_prefix: "lockbox:") }
|
75
|
+
let(:feature) { Flipper::Feature.new(:search, subject) }
|
40
76
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
77
|
+
it_should_behave_like 'a flipper adapter'
|
78
|
+
|
79
|
+
it 'namespaces feature-keys' do
|
80
|
+
subject.add(feature)
|
81
|
+
|
82
|
+
client.with do |conn|
|
83
|
+
expect(conn.smembers("flipper_features")).to eq([])
|
84
|
+
expect(conn.exists?("search")).to eq(false)
|
85
|
+
expect(conn.smembers("lockbox:flipper_features")).to eq(["search"])
|
86
|
+
expect(conn.hgetall("lockbox:search")).not_to eq(nil)
|
87
|
+
end
|
88
|
+
end
|
46
89
|
|
47
|
-
|
48
|
-
|
49
|
-
|
90
|
+
it "can remove namespaced keys" do
|
91
|
+
client.with do |conn|
|
92
|
+
subject.add(feature)
|
93
|
+
expect(conn.smembers("lockbox:flipper_features")).to eq(["search"])
|
50
94
|
|
51
|
-
|
52
|
-
|
95
|
+
subject.remove(feature)
|
96
|
+
expect(conn.smembers("lockbox:flipper_features")).to be_empty
|
97
|
+
end
|
98
|
+
end
|
53
99
|
end
|
54
100
|
end
|
55
101
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flipper-redis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-02-24 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: 1.3.
|
18
|
+
version: 1.3.3
|
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: 1.3.
|
25
|
+
version: 1.3.3
|
27
26
|
- !ruby/object:Gem::Dependency
|
28
27
|
name: redis
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,7 +43,6 @@ dependencies:
|
|
44
43
|
- - "<"
|
45
44
|
- !ruby/object:Gem::Version
|
46
45
|
version: '6'
|
47
|
-
description:
|
48
46
|
email: support@flippercloud.io
|
49
47
|
executables: []
|
50
48
|
extensions: []
|
@@ -57,6 +55,7 @@ files:
|
|
57
55
|
- lib/flipper-redis.rb
|
58
56
|
- lib/flipper/adapters/redis.rb
|
59
57
|
- lib/flipper/adapters/redis_cache.rb
|
58
|
+
- lib/flipper/adapters/redis_shared/methods.rb
|
60
59
|
- lib/flipper/version.rb
|
61
60
|
- spec/flipper/adapters/redis_cache_spec.rb
|
62
61
|
- spec/flipper/adapters/redis_spec.rb
|
@@ -70,8 +69,8 @@ metadata:
|
|
70
69
|
homepage_uri: https://www.flippercloud.io
|
71
70
|
source_code_uri: https://github.com/flippercloud/flipper
|
72
71
|
bug_tracker_uri: https://github.com/flippercloud/flipper/issues
|
73
|
-
changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.3.
|
74
|
-
|
72
|
+
changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.3.3
|
73
|
+
funding_uri: https://github.com/sponsors/flippercloud
|
75
74
|
rdoc_options: []
|
76
75
|
require_paths:
|
77
76
|
- lib
|
@@ -86,8 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
85
|
- !ruby/object:Gem::Version
|
87
86
|
version: '0'
|
88
87
|
requirements: []
|
89
|
-
rubygems_version: 3.5
|
90
|
-
signing_key:
|
88
|
+
rubygems_version: 3.6.5
|
91
89
|
specification_version: 4
|
92
90
|
summary: Redis feature flag adapter for Flipper
|
93
91
|
test_files:
|