flipper-active_support_cache_store 0.11.0.beta9 → 0.11.0.rc1
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
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 20d38d3242893e6a85d8933402c1eee942b416ee
|
|
4
|
+
data.tar.gz: 55ca0340f7250cbd7e8922523b3487da9e10d8f3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9fd879aeedb517919e2b4f338969f893ecfcd9f311f60de934289f51fb18b96843fa27c947ecc9ea523706de3821e8d2cd46e64a2bf368f4b29201fedafa4b3a
|
|
7
|
+
data.tar.gz: 1d17ee8bd8df24c6cae2a383376c11e878559bb6fea3253e8c7827922c1b98c1d6adf9f924ce97f0a52fa2753d68c1ad9dfb2ca097b02980571c0c9ce3247125
|
|
@@ -9,6 +9,7 @@ module Flipper
|
|
|
9
9
|
Version = 'v1'.freeze
|
|
10
10
|
Namespace = "flipper/#{Version}".freeze
|
|
11
11
|
FeaturesKey = "#{Namespace}/features".freeze
|
|
12
|
+
GetAllKey = "#{Namespace}/get_all".freeze
|
|
12
13
|
|
|
13
14
|
# Private
|
|
14
15
|
def self.key_for(key)
|
|
@@ -27,14 +28,12 @@ module Flipper
|
|
|
27
28
|
@name = :active_support_cache_store
|
|
28
29
|
@cache = cache
|
|
29
30
|
@write_options = {}
|
|
30
|
-
@write_options
|
|
31
|
+
@write_options[:expires_in] = expires_in if expires_in
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
# Public
|
|
34
35
|
def features
|
|
35
|
-
|
|
36
|
-
@adapter.features
|
|
37
|
-
end
|
|
36
|
+
read_feature_keys
|
|
38
37
|
end
|
|
39
38
|
|
|
40
39
|
# Public
|
|
@@ -67,17 +66,21 @@ module Flipper
|
|
|
67
66
|
end
|
|
68
67
|
|
|
69
68
|
def get_multi(features)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
read_many_features(features)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def get_all
|
|
73
|
+
if @cache.write(GetAllKey, Time.now.to_i, @write_options.merge(unless_exist: true))
|
|
74
|
+
response = @adapter.get_all
|
|
75
75
|
response.each do |key, value|
|
|
76
76
|
@cache.write(key_for(key), value, @write_options)
|
|
77
|
-
result[key] = value
|
|
78
77
|
end
|
|
78
|
+
@cache.write(FeaturesKey, response.keys.to_set, @write_options)
|
|
79
|
+
response
|
|
80
|
+
else
|
|
81
|
+
features = read_feature_keys.map { |key| Flipper::Feature.new(key, self) }
|
|
82
|
+
read_many_features(features)
|
|
79
83
|
end
|
|
80
|
-
result
|
|
81
84
|
end
|
|
82
85
|
|
|
83
86
|
## Public
|
|
@@ -99,6 +102,33 @@ module Flipper
|
|
|
99
102
|
def key_for(key)
|
|
100
103
|
self.class.key_for(key)
|
|
101
104
|
end
|
|
105
|
+
|
|
106
|
+
# Internal: Returns an array of the known feature keys.
|
|
107
|
+
def read_feature_keys
|
|
108
|
+
@cache.fetch(FeaturesKey, @write_options) { @adapter.features }
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Internal: Given an array of features, attempts to read through cache in
|
|
112
|
+
# as few network calls as possible.
|
|
113
|
+
def read_many_features(features)
|
|
114
|
+
keys = features.map { |feature| key_for(feature.key) }
|
|
115
|
+
cache_result = @cache.read_multi(*keys)
|
|
116
|
+
uncached_features = features.reject { |feature| cache_result[key_for(feature)] }
|
|
117
|
+
|
|
118
|
+
if uncached_features.any?
|
|
119
|
+
response = @adapter.get_multi(uncached_features)
|
|
120
|
+
response.each do |key, value|
|
|
121
|
+
@cache.write(key_for(key), value, @write_options)
|
|
122
|
+
cache_result[key_for(key)] = value
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
result = {}
|
|
127
|
+
features.each do |feature|
|
|
128
|
+
result[feature.key] = cache_result[key_for(feature.key)]
|
|
129
|
+
end
|
|
130
|
+
result
|
|
131
|
+
end
|
|
102
132
|
end
|
|
103
133
|
end
|
|
104
134
|
end
|
data/lib/flipper/version.rb
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
require 'helper'
|
|
2
2
|
require 'active_support/cache'
|
|
3
|
+
require 'active_support/cache/dalli_store'
|
|
3
4
|
require 'flipper/adapters/memory'
|
|
5
|
+
require 'flipper/adapters/operation_logger'
|
|
4
6
|
require 'flipper/adapters/active_support_cache_store'
|
|
5
7
|
require 'flipper/spec/shared_adapter_specs'
|
|
6
8
|
|
|
7
9
|
RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
|
|
8
|
-
let(:memory_adapter)
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
let(:memory_adapter) do
|
|
11
|
+
Flipper::Adapters::OperationLogger.new(Flipper::Adapters::Memory.new)
|
|
12
|
+
end
|
|
13
|
+
let(:cache) { ActiveSupport::Cache::DalliStore.new }
|
|
14
|
+
let(:adapter) { described_class.new(memory_adapter, cache, expires_in: 10.seconds) }
|
|
11
15
|
let(:flipper) { Flipper.new(adapter) }
|
|
12
16
|
|
|
13
17
|
subject { adapter }
|
|
14
18
|
|
|
19
|
+
before do
|
|
20
|
+
cache.clear
|
|
21
|
+
end
|
|
22
|
+
|
|
15
23
|
it_should_behave_like 'a flipper adapter'
|
|
16
24
|
|
|
17
25
|
describe '#remove' do
|
|
@@ -31,6 +39,8 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
|
|
|
31
39
|
stats.enable
|
|
32
40
|
search.enable
|
|
33
41
|
|
|
42
|
+
memory_adapter.reset
|
|
43
|
+
|
|
34
44
|
adapter.get(stats)
|
|
35
45
|
expect(cache.read(described_class.key_for(search))).to be(nil)
|
|
36
46
|
expect(cache.read(described_class.key_for(other))).to be(nil)
|
|
@@ -39,6 +49,37 @@ RSpec.describe Flipper::Adapters::ActiveSupportCacheStore do
|
|
|
39
49
|
|
|
40
50
|
expect(cache.read(described_class.key_for(search))[:boolean]).to eq('true')
|
|
41
51
|
expect(cache.read(described_class.key_for(other))[:boolean]).to be(nil)
|
|
52
|
+
|
|
53
|
+
adapter.get_multi([stats, search, other])
|
|
54
|
+
adapter.get_multi([stats, search, other])
|
|
55
|
+
expect(memory_adapter.count(:get_multi)).to eq(1)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe '#get_all' do
|
|
60
|
+
let(:stats) { flipper[:stats] }
|
|
61
|
+
let(:search) { flipper[:search] }
|
|
62
|
+
|
|
63
|
+
before do
|
|
64
|
+
stats.enable
|
|
65
|
+
search.add
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'warms all features' do
|
|
69
|
+
adapter.get_all
|
|
70
|
+
expect(cache.read(described_class.key_for(stats))[:boolean]).to eq('true')
|
|
71
|
+
expect(cache.read(described_class.key_for(search))[:boolean]).to be(nil)
|
|
72
|
+
expect(cache.read(described_class::GetAllKey)).to be_within(2).of(Time.now.to_i)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'returns same result when already cached' do
|
|
76
|
+
expect(adapter.get_all).to eq(adapter.get_all)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'only invokes one call to wrapped adapter' do
|
|
80
|
+
memory_adapter.reset
|
|
81
|
+
5.times { adapter.get_all }
|
|
82
|
+
expect(memory_adapter.count(:get_all)).to eq(1)
|
|
42
83
|
end
|
|
43
84
|
end
|
|
44
85
|
|
metadata
CHANGED
|
@@ -1,14 +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: 0.11.0.
|
|
4
|
+
version: 0.11.0.rc1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- John Nunemaker
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-11-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: flipper
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.11.0.
|
|
19
|
+
version: 0.11.0.rc1
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.11.0.
|
|
26
|
+
version: 0.11.0.rc1
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: activesupport
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|