flipper-cloud 0.23.1 → 0.24.0

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
  SHA256:
3
- metadata.gz: bdc9bab38dc9eda1a623130fc95ef4ea352b3acaaf83f8c36cdc013c8a5bc3c4
4
- data.tar.gz: cea3e86dd52a6c74fbd01e93782456f42b5058631b377c58f7d7610b22d81cb3
3
+ metadata.gz: 2f9785229e28e7184b68cafc4a40d4f25243af4f538b45fe06db8865ddc24287
4
+ data.tar.gz: afc81309d68ea13ca32d5f1fa802c9ae7b388b157f54276a57df4385205477ac
5
5
  SHA512:
6
- metadata.gz: 6c5a1104978d3f190687d4374c44a1887953b2955c803eecb995d597662420d2b4edb5d4d5bcb420c444167669c709b8718d7966916034dcee1ddca408b6d6b3
7
- data.tar.gz: 3e195dd488dcd230d0dd8f19162b05cac2b663f893b1f3509ffc681557ee3cd79e019d499d78295227d3603899e575daaad2a94c5878de2291ccac60dabcad45
6
+ metadata.gz: f5e33a87199655dcfbfe6011d47c3b14731947854151657c9011e0553d490c3a63d06321d3caed63737d871520928f31ca1e599e9ff428855340e0bec33f7fa8
7
+ data.tar.gz: 0f8c2263b85318a26ac4f287cf2bdaa0c01eb69e05a12cc388502ff8a3b000dee5b0cdfa75ee2a8b42f51525ba91b9aa70bfa6cfcaa65b12c9a03310f25b4236
@@ -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
@@ -75,7 +78,6 @@ module Flipper
75
78
  end
76
79
  self.sync_method = options[:sync_method] if options[:sync_method]
77
80
 
78
- @instrumenter = options.fetch(:instrumenter, Instrumenters::Noop)
79
81
  @read_timeout = options.fetch(:read_timeout) { ENV.fetch("FLIPPER_CLOUD_READ_TIMEOUT", 5).to_f }
80
82
  @open_timeout = options.fetch(:open_timeout) { ENV.fetch("FLIPPER_CLOUD_OPEN_TIMEOUT", 5).to_f }
81
83
  @write_timeout = options.fetch(:write_timeout) { ENV.fetch("FLIPPER_CLOUD_WRITE_TIMEOUT", 5).to_f }
@@ -85,6 +87,16 @@ module Flipper
85
87
  @debug_output = options[:debug_output]
86
88
  @adapter_block = ->(adapter) { adapter }
87
89
  self.url = options.fetch(:url) { ENV.fetch("FLIPPER_CLOUD_URL", DEFAULT_URL) }
90
+
91
+ instrumenter = options.fetch(:instrumenter, Instrumenters::Noop)
92
+
93
+ # This is alpha. Don't use this unless you are me. And you are not me.
94
+ cloud_instrument = options.fetch(:cloud_instrument) { ENV["FLIPPER_CLOUD_INSTRUMENT"] == "1" }
95
+ @instrumenter = if cloud_instrument
96
+ Instrumenter.new(brow: brow, instrumenter: instrumenter)
97
+ else
98
+ instrumenter
99
+ end
88
100
  end
89
101
 
90
102
  # Public: Read or customize the http adapter. Calling without a block will
@@ -116,6 +128,24 @@ module Flipper
116
128
  }).call
117
129
  end
118
130
 
131
+ def brow
132
+ uri = URI.parse(url)
133
+ uri.path = "#{uri.path}/events".squeeze("/")
134
+ events_url = uri.to_s
135
+
136
+ Registry.default.fetch(events_url) {
137
+ Brow::Client.new({
138
+ url: events_url,
139
+ headers: {
140
+ "Accept" => "application/json",
141
+ "Content-Type" => "application/json",
142
+ "User-Agent" => "Flipper v#{VERSION} via Brow v#{Brow::VERSION}",
143
+ "Flipper-Cloud-Token" => @token,
144
+ }
145
+ })
146
+ }
147
+ end
148
+
119
149
  # Public: The method that will be used to synchronize local adapter with
120
150
  # cloud. (default: :poll, will be :webhook if sync_secret is set).
121
151
  def sync_method
@@ -157,5 +187,3 @@ module Flipper
157
187
  end
158
188
  end
159
189
  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
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '0.23.1'.freeze
2
+ VERSION = '0.24.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
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.24.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-02-17 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.24.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.24.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