flipper-cloud 0.12.2 → 0.13.0.beta1

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: 2c16c266053c1d551d7c1bb269dd905d1645a6dd
4
- data.tar.gz: 8482911ea237a5b25dc683fa45586addb9ceaea0
3
+ metadata.gz: 50eb398f4f63e0cbd275e6d07aa287704ecfdcd3
4
+ data.tar.gz: 6f3f4f0715b503a3289849669a95a429f645d2f7
5
5
  SHA512:
6
- metadata.gz: 90feb00b50804cbace1f6f42b2896b0f501349d5ff2d4b2bbfa86483d1976a9b4c05cbbb6f4d42154c45d7476dcb35e8017773b3cdac68b871a1d6aad7493f7b
7
- data.tar.gz: 93d224f2254a8fd19f65854da1969ab0f1b99b5fab625dd383fc8bb73b861807d65e5c59779f4abb04f2646b0499506a29f01efd0d8f8a692fbda1b38e0d1bfc
6
+ metadata.gz: 4fc94db45b534f16013632befc7a65ae1cae65d0c0e88b008da6879fd7077c6e96f7313062c1afc6813361b42ab4623d5c4fcfba144e0c788bf7709749017f5a
7
+ data.tar.gz: 1937f6db0ee4e4446c6147f7bc848aa42c893b59365386b67545c1743f113f3fb99d88ba6959f91d43d62e4bc57d35365e8ff321cf2f81f012fd47b85201b3dc
@@ -0,0 +1,36 @@
1
+ # This is an example of using cloud with a local adapter. All cloud feature
2
+ # changes are synced to the local adapter on an interval. All feature reads are
3
+ # directed to the local adapter, which means reads are fast and not dependent on
4
+ # cloud being available. You can turn internet on/off and more and this should
5
+ # never raise. You could get a slow request every now and then if cloud is
6
+ # unavailable, but we are hoping to fix that soon by doing the cloud update in a
7
+ # background thread.
8
+ require File.expand_path('../../example_setup', __FILE__)
9
+
10
+ require 'logger'
11
+ require 'flipper/cloud'
12
+ require 'flipper/adapters/redis'
13
+
14
+ token = ENV.fetch("TOKEN") { abort "TOKEN environment variable not set." }
15
+ feature_name = ENV.fetch("FEATURE") { "testing" }.to_sym
16
+
17
+ redis = Redis.new(logger: Logger.new(STDOUT))
18
+ redis.flushdb
19
+
20
+ Flipper.configure do |config|
21
+ config.default do
22
+ Flipper::Cloud.new(token) do |cloud|
23
+ cloud.debug_output = STDOUT
24
+ cloud.local_adapter = Flipper::Adapters::Redis.new(redis)
25
+ cloud.sync_interval = 10_000
26
+ end
27
+ end
28
+ end
29
+
30
+ loop do
31
+ # Should only print out http call every 10 seconds
32
+ p Flipper.enabled?(feature_name)
33
+ puts "\n\n"
34
+
35
+ sleep 1
36
+ end
@@ -1,4 +1,6 @@
1
1
  require "flipper/adapters/http"
2
+ require "flipper/adapters/memory"
3
+ require "flipper/adapters/sync"
2
4
  require "flipper/instrumenters/noop"
3
5
 
4
6
  module Flipper
@@ -36,11 +38,26 @@ module Flipper
36
38
  # configuration.instrumenter = ActiveSupport::Notifications
37
39
  attr_accessor :instrumenter
38
40
 
41
+ # Public: Local adapter that all reads should go to in order to ensure
42
+ # latency is low and resiliency is high. This adapter is automatically
43
+ # kept in sync with cloud.
44
+ #
45
+ # # for example, to use active record you could do:
46
+ # configuration = Flipper::Cloud::Configuration.new
47
+ # configuration.local_adapter = Flipper::Adapters::ActiveRecord.new
48
+ attr_accessor :local_adapter
49
+
50
+ # Public: Number of milliseconds between attempts to bring the local in
51
+ # sync with cloud (default: 10_000 aka 10 seconds).
52
+ attr_accessor :sync_interval
53
+
39
54
  def initialize(options = {})
40
55
  @token = options.fetch(:token)
41
56
  @instrumenter = options.fetch(:instrumenter, Instrumenters::Noop)
42
57
  @read_timeout = options.fetch(:read_timeout, 5)
43
58
  @open_timeout = options.fetch(:open_timeout, 5)
59
+ @sync_interval = options.fetch(:sync_interval, 10_000)
60
+ @local_adapter = options.fetch(:local_adapter) { Adapters::Memory.new }
44
61
  @debug_output = options[:debug_output]
45
62
  @adapter_block = ->(adapter) { adapter }
46
63
 
@@ -48,7 +65,7 @@ module Flipper
48
65
  end
49
66
 
50
67
  # Public: Read or customize the http adapter. Calling without a block will
51
- # perform a read. Calling with a block yields the http_adapter
68
+ # perform a read. Calling with a block yields the cloud adapter
52
69
  # for customization.
53
70
  #
54
71
  # # for example, to instrument the http calls, you can wrap the http
@@ -62,23 +79,34 @@ module Flipper
62
79
  if block_given?
63
80
  @adapter_block = block
64
81
  else
65
- @adapter_block.call(http_adapter)
82
+ @adapter_block.call sync_adapter
66
83
  end
67
84
  end
68
85
 
69
- # Public: Set url and uri for the http adapter.
86
+ # Public: Set url for the http adapter.
70
87
  attr_writer :url
71
88
 
72
89
  private
73
90
 
91
+ def sync_adapter
92
+ sync_options = {
93
+ instrumenter: instrumenter,
94
+ interval: sync_interval,
95
+ }
96
+ Flipper::Adapters::Sync.new(local_adapter, http_adapter, sync_options)
97
+ end
98
+
74
99
  def http_adapter
75
- Flipper::Adapters::Http.new(url: @url,
76
- read_timeout: @read_timeout,
77
- open_timeout: @open_timeout,
78
- debug_output: @debug_output,
79
- headers: {
80
- "Feature-Flipper-Token" => @token,
81
- })
100
+ http_options = {
101
+ url: @url,
102
+ read_timeout: @read_timeout,
103
+ open_timeout: @open_timeout,
104
+ debug_output: @debug_output,
105
+ headers: {
106
+ "Feature-Flipper-Token" => @token,
107
+ },
108
+ }
109
+ Flipper::Adapters::Http.new(http_options)
82
110
  end
83
111
  end
84
112
  end
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '0.12.2'.freeze
2
+ VERSION = '0.13.0.beta1'.freeze
3
3
  end
@@ -28,17 +28,36 @@ RSpec.describe Flipper::Cloud::Configuration do
28
28
  expect(instance.open_timeout).to eq(5)
29
29
  end
30
30
 
31
+ it "can set sync_interval" do
32
+ instance = described_class.new(required_options.merge(sync_interval: 1_000))
33
+ expect(instance.sync_interval).to eq(1_000)
34
+ end
35
+
36
+ it "passes sync_interval into sync adapter" do
37
+ # The initial sync of http to local invokes this web request.
38
+ stub_request(:get, /featureflipper\.com/).to_return(status: 200, body: "{}")
39
+
40
+ instance = described_class.new(required_options.merge(sync_interval: 1_000))
41
+ expect(instance.adapter.synchronizer.interval).to be(1_000)
42
+ end
43
+
31
44
  it "can set debug_output" do
32
45
  instance = described_class.new(required_options.merge(debug_output: STDOUT))
33
46
  expect(instance.debug_output).to eq(STDOUT)
34
47
  end
35
48
 
36
49
  it "defaults adapter block" do
50
+ # The initial sync of http to local invokes this web request.
51
+ stub_request(:get, /featureflipper\.com/).to_return(status: 200, body: "{}")
52
+
37
53
  instance = described_class.new(required_options)
38
- expect(instance.adapter).to be_instance_of(Flipper::Adapters::Http)
54
+ expect(instance.adapter).to be_instance_of(Flipper::Adapters::Sync)
39
55
  end
40
56
 
41
57
  it "can override adapter block" do
58
+ # The initial sync of http to local invokes this web request.
59
+ stub_request(:get, /featureflipper\.com/).to_return(status: 200, body: "{}")
60
+
42
61
  instance = described_class.new(required_options)
43
62
  instance.adapter do |adapter|
44
63
  Flipper::Adapters::Instrumented.new(adapter)
@@ -1,15 +1,21 @@
1
1
  require 'helper'
2
2
  require 'flipper/cloud'
3
3
  require 'flipper/adapters/instrumented'
4
+ require 'flipper/instrumenters/memory'
4
5
 
5
6
  RSpec.describe Flipper::Cloud do
7
+ before do
8
+ stub_request(:get, /featureflipper\.com/).to_return(status: 200, body: "{}")
9
+ end
10
+
6
11
  context "initialize with token" do
7
12
  let(:token) { 'asdf' }
8
13
 
9
14
  before do
10
15
  @instance = described_class.new(token)
11
16
  memoized_adapter = @instance.adapter
12
- @http_adapter = memoized_adapter.adapter
17
+ sync_adapter = memoized_adapter.adapter
18
+ @http_adapter = sync_adapter.instance_variable_get('@remote')
13
19
  @http_client = @http_adapter.instance_variable_get('@client')
14
20
  end
15
21
 
@@ -40,9 +46,12 @@ RSpec.describe Flipper::Cloud do
40
46
 
41
47
  context 'initialize with token and options' do
42
48
  before do
49
+ stub_request(:get, /fakeflipper\.com/).to_return(status: 200, body: "{}")
50
+
43
51
  @instance = described_class.new('asdf', url: 'https://www.fakeflipper.com/sadpanda')
44
52
  memoized_adapter = @instance.adapter
45
- @http_adapter = memoized_adapter.adapter
53
+ sync_adapter = memoized_adapter.adapter
54
+ @http_adapter = sync_adapter.instance_variable_get('@remote')
46
55
  @http_client = @http_adapter.instance_variable_get('@client')
47
56
  end
48
57
 
@@ -55,7 +64,7 @@ RSpec.describe Flipper::Cloud do
55
64
  end
56
65
 
57
66
  it 'can set instrumenter' do
58
- instrumenter = Object.new
67
+ instrumenter = Flipper::Instrumenters::Memory.new
59
68
  instance = described_class.new('asdf', instrumenter: instrumenter)
60
69
  expect(instance.instrumenter).to be(instrumenter)
61
70
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper-cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.2
4
+ version: 0.13.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-22 00:00:00.000000000 Z
11
+ date: 2018-03-03 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.12.2
19
+ version: 0.13.0.beta1
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.12.2
26
+ version: 0.13.0.beta1
27
27
  description: FeatureFlipper.com adapter for Flipper
28
28
  email:
29
29
  - nunemaker@gmail.com
@@ -33,6 +33,7 @@ extra_rdoc_files: []
33
33
  files:
34
34
  - examples/cloud/basic.rb
35
35
  - examples/cloud/cached_in_memory.rb
36
+ - examples/cloud/local_adapter.rb
36
37
  - flipper-cloud.gemspec
37
38
  - lib/flipper-cloud.rb
38
39
  - lib/flipper/cloud.rb
@@ -55,12 +56,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
55
56
  version: '0'
56
57
  required_rubygems_version: !ruby/object:Gem::Requirement
57
58
  requirements:
58
- - - ">="
59
+ - - ">"
59
60
  - !ruby/object:Gem::Version
60
- version: '0'
61
+ version: 1.3.1
61
62
  requirements: []
62
63
  rubyforge_project:
63
- rubygems_version: 2.5.2
64
+ rubygems_version: 2.6.14
64
65
  signing_key:
65
66
  specification_version: 4
66
67
  summary: FeatureFlipper.com adapter for Flipper