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 +4 -4
- data/flipper-cloud.gemspec +1 -0
- data/lib/flipper/cloud/configuration.rb +31 -12
- data/lib/flipper/cloud/instrumenter.rb +43 -0
- data/lib/flipper/cloud/registry.rb +46 -0
- data/lib/flipper/cloud.rb +4 -10
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/cloud/configuration_spec.rb +17 -0
- data/spec/flipper/cloud/middleware_spec.rb +1 -1
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7502697176d9e926cf7cf93c18ed11d4f15fa342287dbe2cd757aaf70b62ddfc
|
4
|
+
data.tar.gz: f1efff2fbcc4ebb9c1b0e09cfea3ca68f653a494566a7e52a7b7d5088c7cac72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c1509933e50811a1d366228639e7a3ddf9d6549778eb228da64e477e16561deb4190635d1c9c0993d284635aaba379e7fd735ba796f78ae5666fa95241dc13c
|
7
|
+
data.tar.gz: ef398dc3057a49a886899b61c3f5290fe13e3f6d8adeb48922ade8ba8d3520f3b4b96f3ba861da0642056b0a84bf8137717b9c4b00f3dd8c1e8af156516920e3
|
data/flipper-cloud.gemspec
CHANGED
@@ -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 = {}
|
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
|
-
|
44
|
-
|
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
|
data/lib/flipper/version.rb
CHANGED
@@ -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
|
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.
|
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-
|
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.
|
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.
|
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
|