flipper-cloud 0.23.1 → 0.25.0

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
  SHA256:
3
- metadata.gz: bdc9bab38dc9eda1a623130fc95ef4ea352b3acaaf83f8c36cdc013c8a5bc3c4
4
- data.tar.gz: cea3e86dd52a6c74fbd01e93782456f42b5058631b377c58f7d7610b22d81cb3
3
+ metadata.gz: 7502697176d9e926cf7cf93c18ed11d4f15fa342287dbe2cd757aaf70b62ddfc
4
+ data.tar.gz: f1efff2fbcc4ebb9c1b0e09cfea3ca68f653a494566a7e52a7b7d5088c7cac72
5
5
  SHA512:
6
- metadata.gz: 6c5a1104978d3f190687d4374c44a1887953b2955c803eecb995d597662420d2b4edb5d4d5bcb420c444167669c709b8718d7966916034dcee1ddca408b6d6b3
7
- data.tar.gz: 3e195dd488dcd230d0dd8f19162b05cac2b663f893b1f3509ffc681557ee3cd79e019d499d78295227d3603899e575daaad2a94c5878de2291ccac60dabcad45
6
+ metadata.gz: 8c1509933e50811a1d366228639e7a3ddf9d6549778eb228da64e477e16561deb4190635d1c9c0993d284635aaba379e7fd735ba796f78ae5666fa95241dc13c
7
+ data.tar.gz: ef398dc3057a49a886899b61c3f5290fe13e3f6d8adeb48922ade8ba8d3520f3b4b96f3ba861da0642056b0a84bf8137717b9c4b00f3dd8c1e8af156516920e3
@@ -24,4 +24,5 @@ Gem::Specification.new do |gem|
24
24
  gem.metadata = Flipper::METADATA
25
25
 
26
26
  gem.add_dependency 'flipper', "~> #{Flipper::VERSION}"
27
+ gem.add_dependency "brow", "~> 0.4.1"
27
28
  end
@@ -3,6 +3,9 @@ require "flipper/adapters/http"
3
3
  require "flipper/adapters/memory"
4
4
  require "flipper/adapters/dual_write"
5
5
  require "flipper/adapters/sync"
6
+ require "flipper/cloud/instrumenter"
7
+ require "flipper/cloud/registry"
8
+ require "brow"
6
9
 
7
10
  module Flipper
8
11
  module Cloud
@@ -70,12 +73,6 @@ module Flipper
70
73
  raise ArgumentError, "Flipper::Cloud token is missing. Please set FLIPPER_CLOUD_TOKEN or provide the token (e.g. Flipper::Cloud.new(token: 'token'))."
71
74
  end
72
75
 
73
- if ENV["FLIPPER_CLOUD_SYNC_METHOD"]
74
- warn "FLIPPER_CLOUD_SYNC_METHOD is deprecated and has no effect."
75
- end
76
- self.sync_method = options[:sync_method] if options[:sync_method]
77
-
78
- @instrumenter = options.fetch(:instrumenter, Instrumenters::Noop)
79
76
  @read_timeout = options.fetch(:read_timeout) { ENV.fetch("FLIPPER_CLOUD_READ_TIMEOUT", 5).to_f }
80
77
  @open_timeout = options.fetch(:open_timeout) { ENV.fetch("FLIPPER_CLOUD_OPEN_TIMEOUT", 5).to_f }
81
78
  @write_timeout = options.fetch(:write_timeout) { ENV.fetch("FLIPPER_CLOUD_WRITE_TIMEOUT", 5).to_f }
@@ -85,6 +82,16 @@ module Flipper
85
82
  @debug_output = options[:debug_output]
86
83
  @adapter_block = ->(adapter) { adapter }
87
84
  self.url = options.fetch(:url) { ENV.fetch("FLIPPER_CLOUD_URL", DEFAULT_URL) }
85
+
86
+ instrumenter = options.fetch(:instrumenter, Instrumenters::Noop)
87
+
88
+ # This is alpha. Don't use this unless you are me. And you are not me.
89
+ cloud_instrument = options.fetch(:cloud_instrument) { ENV["FLIPPER_CLOUD_INSTRUMENT"] == "1" }
90
+ @instrumenter = if cloud_instrument
91
+ Instrumenter.new(brow: brow, instrumenter: instrumenter)
92
+ else
93
+ instrumenter
94
+ end
88
95
  end
89
96
 
90
97
  # Public: Read or customize the http adapter. Calling without a block will
@@ -116,16 +123,30 @@ module Flipper
116
123
  }).call
117
124
  end
118
125
 
126
+ def brow
127
+ uri = URI.parse(url)
128
+ uri.path = "#{uri.path}/events".squeeze("/")
129
+ events_url = uri.to_s
130
+
131
+ Registry.default.fetch(events_url) {
132
+ Brow::Client.new({
133
+ url: events_url,
134
+ headers: {
135
+ "Accept" => "application/json",
136
+ "Content-Type" => "application/json",
137
+ "User-Agent" => "Flipper v#{VERSION} via Brow v#{Brow::VERSION}",
138
+ "Flipper-Cloud-Token" => @token,
139
+ }
140
+ })
141
+ }
142
+ end
143
+
119
144
  # Public: The method that will be used to synchronize local adapter with
120
145
  # cloud. (default: :poll, will be :webhook if sync_secret is set).
121
146
  def sync_method
122
147
  sync_secret ? :webhook : :poll
123
148
  end
124
149
 
125
- def sync_method=(_)
126
- warn "Flipper::Cloud: sync_method is deprecated and has no effect."
127
- end
128
-
129
150
  private
130
151
 
131
152
  def app_adapter
@@ -157,5 +178,3 @@ module Flipper
157
178
  end
158
179
  end
159
180
  end
160
-
161
- # "FLIPPER_TIMESTAMP".freeze => Flipper::Timestamp.generate.to_s,
@@ -0,0 +1,43 @@
1
+ require "delegate"
2
+ require "flipper/instrumenters/noop"
3
+
4
+ module Flipper
5
+ module Cloud
6
+ class Instrumenter < SimpleDelegator
7
+ def initialize(options = {})
8
+ @brow = options.fetch(:brow)
9
+ @instrumenter = options.fetch(:instrumenter, Instrumenters::Noop)
10
+ super @instrumenter
11
+ end
12
+
13
+ def instrument(name, payload = {}, &block)
14
+ result = @instrumenter.instrument(name, payload, &block)
15
+ push name, payload
16
+ result
17
+ end
18
+
19
+ private
20
+
21
+ def push(name, payload)
22
+ return unless name == Flipper::Feature::InstrumentationName
23
+ return unless :enabled? == payload[:operation]
24
+
25
+ dimensions = {
26
+ "feature" => payload[:feature_name].to_s,
27
+ "result" => payload[:result].to_s,
28
+ }
29
+ if (thing = payload[:thing])
30
+ dimensions["flipper_id"] = thing.value.to_s
31
+ end
32
+
33
+ event = {
34
+ type: "enabled",
35
+ dimensions: dimensions,
36
+ measures: {},
37
+ ts: Time.now.utc,
38
+ }
39
+ @brow.push event
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,46 @@
1
+ require "thread"
2
+
3
+ module Flipper
4
+ module Cloud
5
+ class Registry
6
+ def self.default
7
+ @default ||= new
8
+ end
9
+
10
+ def initialize
11
+ @mutex = Mutex.new
12
+ @data = {}
13
+ end
14
+
15
+ def fetch(key, &block)
16
+ @mutex.synchronize do
17
+ if data = @data[key]
18
+ data
19
+ else
20
+ @data[key] = yield
21
+ end
22
+ end
23
+ end
24
+
25
+ def keys
26
+ @mutex.synchronize do
27
+ @data.keys
28
+ end
29
+ end
30
+
31
+ def each(&block)
32
+ data = @mutex.synchronize do
33
+ @data.dup
34
+ end
35
+
36
+ data.each(&block)
37
+ end
38
+
39
+ def clear
40
+ @mutex.synchronize do
41
+ @data = {}
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
data/lib/flipper/cloud.rb CHANGED
@@ -15,14 +15,7 @@ module Flipper
15
15
  # options - The Hash of options. See Flipper::Cloud::Configuration.
16
16
  # block - The block that configuration will be yielded to allowing you to
17
17
  # customize this cloud instance and its adapter.
18
- def self.new(options = {}, deprecated_options = {})
19
- if options.is_a?(String)
20
- warn "`Flipper::Cloud.new(token)` is deprecated. Use `Flipper::Cloud.new(token: token)` " +
21
- "or set the `FLIPPER_CLOUD_TOKEN` environment variable.\n" +
22
- caller[0]
23
- options = deprecated_options.merge(token: options)
24
- end
25
-
18
+ def self.new(options = {})
26
19
  configuration = Configuration.new(options)
27
20
  yield configuration if block_given?
28
21
  DSL.new(configuration)
@@ -40,8 +33,9 @@ module Flipper
40
33
  builder.use Flipper::Cloud::Middleware, env_key: env_key
41
34
  builder.run app
42
35
  klass = self
43
- builder.define_singleton_method(:inspect) { klass.inspect } # pretty rake routes output
44
- builder
36
+ app = builder.to_app
37
+ app.define_singleton_method(:inspect) { klass.inspect } # pretty rake routes output
38
+ app
45
39
  end
46
40
 
47
41
  # Private: Configure Flipper to use Cloud by default
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '0.23.1'.freeze
2
+ VERSION = '0.25.0'.freeze
3
3
  end
@@ -240,4 +240,21 @@ RSpec.describe Flipper::Cloud::Configuration do
240
240
  expect(all["search"][:boolean]).to eq("true")
241
241
  expect(all["history"][:boolean]).to eq(nil)
242
242
  end
243
+
244
+ it "can setup brow to report events to cloud" do
245
+ # skip logging brow
246
+ Brow.logger = Logger.new(File::NULL)
247
+ brow = described_class.new(required_options).brow
248
+
249
+ stub = stub_request(:post, "https://www.flippercloud.io/adapter/events")
250
+ .with { |request|
251
+ data = JSON.parse(request.body)
252
+ data.keys == ["uuid", "messages"] && data["messages"] == [{"n" => 1}]
253
+ }
254
+ .to_return(status: 201, body: "{}", headers: {})
255
+
256
+ brow.push({"n" => 1})
257
+ brow.worker.stop
258
+ expect(stub).to have_been_requested.times(1)
259
+ end
243
260
  end
@@ -267,7 +267,7 @@ RSpec.describe Flipper::Cloud::Middleware do
267
267
 
268
268
  describe 'Inspecting the built Rack app' do
269
269
  it 'returns a String' do
270
- expect(Flipper::Cloud.app(flipper).inspect).to be_a(String)
270
+ expect(Flipper::Cloud.app(flipper).inspect).to eq("Flipper::Cloud")
271
271
  end
272
272
  end
273
273
 
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.23.1
4
+ version: 0.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-19 00:00:00.000000000 Z
11
+ date: 2022-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: flipper
@@ -16,14 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.23.1
19
+ version: 0.25.0
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.23.1
26
+ version: 0.25.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: brow
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.4.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.4.1
27
41
  description:
28
42
  email:
29
43
  - nunemaker@gmail.com
@@ -42,8 +56,10 @@ files:
42
56
  - lib/flipper/cloud/configuration.rb
43
57
  - lib/flipper/cloud/dsl.rb
44
58
  - lib/flipper/cloud/engine.rb
59
+ - lib/flipper/cloud/instrumenter.rb
45
60
  - lib/flipper/cloud/message_verifier.rb
46
61
  - lib/flipper/cloud/middleware.rb
62
+ - lib/flipper/cloud/registry.rb
47
63
  - lib/flipper/cloud/routes.rb
48
64
  - lib/flipper/version.rb
49
65
  - spec/flipper/cloud/configuration_spec.rb