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: 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