flipper-active_support_cache_store 0.11.0.beta9 → 0.11.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a0e8d7316856c656b4b521d6134b81d974481144
4
- data.tar.gz: 8025ed93371a25fb3f7a1c1c46b75b07d99e9fcc
3
+ metadata.gz: 20d38d3242893e6a85d8933402c1eee942b416ee
4
+ data.tar.gz: 55ca0340f7250cbd7e8922523b3487da9e10d8f3
5
5
  SHA512:
6
- metadata.gz: a7e61ade46c07e82f6384cef0a0cb70c36f1d1a84519a021cb8f5ef38195a539af5944b473d092df19bd79120faffcd43a005c39e1f558521560f4c1bc4d4cfe
7
- data.tar.gz: d460d2e9f218f7ae7b335c5197cc885b5e0d258746e6bf5f17764ad4dc0503e28dcbdd1d4722b46a91fdb757aa1bd9bc7e13e6661c8f4d7fae7213b8fb5c2bfe
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.merge!(expires_in: expires_in) if expires_in
31
+ @write_options[:expires_in] = expires_in if expires_in
31
32
  end
32
33
 
33
34
  # Public
34
35
  def features
35
- @cache.fetch(FeaturesKey, @write_options) do
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
- keys = features.map { |feature| key_for(feature.key) }
71
- result = @cache.read_multi(keys)
72
- uncached_features = features.reject { |feature| result[feature.key] }
73
- if uncached_features.any?
74
- response = @adapter.get_multi(uncached_features)
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
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '0.11.0.beta9'.freeze
2
+ VERSION = '0.11.0.rc1'.freeze
3
3
  end
@@ -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) { Flipper::Adapters::Memory.new }
9
- let(:cache) { ActiveSupport::Cache::MemoryStore.new }
10
- let(:adapter) { described_class.new(memory_adapter, cache) }
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.beta9
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-10-28 00:00:00.000000000 Z
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.beta9
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.beta9
26
+ version: 0.11.0.rc1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement