determinator 2.3.1 → 2.4.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/.circleci/config.yml +12 -0
- data/CHANGELOG.md +5 -0
- data/README.md +67 -1
- data/determinator.gemspec +2 -1
- data/lib/determinator.rb +2 -0
- data/lib/determinator/tracking.rb +62 -0
- data/lib/determinator/tracking/context.rb +15 -0
- data/lib/determinator/tracking/determination.rb +18 -0
- data/lib/determinator/tracking/rack/middleware.rb +24 -0
- data/lib/determinator/tracking/request.rb +20 -0
- data/lib/determinator/tracking/sidekiq/middleware.rb +27 -0
- data/lib/determinator/tracking/tracker.rb +43 -0
- data/lib/determinator/version.rb +1 -1
- metadata +26 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63baaf3ee379eef31694ec105e48407970d0e53e6906af8e9a1746cfac5ca5e4
|
4
|
+
data.tar.gz: 88b70dc55dedc32c98dc1eb3619fd420471127c812a7cdda7086c13349d3bdca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ea1835cd7e0953c5d6747bbcbddfc43804cd33ffc3ed136c72ede003c2a24c9357c7746081370404b9851788a0b64b9d45a633657365524ed77cf6a5a69bf67
|
7
|
+
data.tar.gz: 2db13fd8793c724554c2ba4766e3e769eb5d9e4042481b153a205337c5b0cfaad1bd6a691b552ee9a25109f9b8bb7b6dc6837570e909bf5d60fab1f4fe056e86
|
data/.circleci/config.yml
CHANGED
@@ -10,6 +10,10 @@ jobs:
|
|
10
10
|
steps:
|
11
11
|
- checkout
|
12
12
|
|
13
|
+
- run:
|
14
|
+
name: Install bundler
|
15
|
+
command: gem install bundler -v 2.1.4
|
16
|
+
|
13
17
|
- run:
|
14
18
|
name: Bundle Install
|
15
19
|
command: bundle install
|
@@ -30,6 +34,10 @@ jobs:
|
|
30
34
|
steps:
|
31
35
|
- checkout
|
32
36
|
|
37
|
+
- run:
|
38
|
+
name: Install bundler
|
39
|
+
command: gem install bundler -v 2.1.4
|
40
|
+
|
33
41
|
- run:
|
34
42
|
name: Bundle Install
|
35
43
|
command: bundle install
|
@@ -50,6 +58,10 @@ jobs:
|
|
50
58
|
steps:
|
51
59
|
- checkout
|
52
60
|
|
61
|
+
- run:
|
62
|
+
name: Install bundler
|
63
|
+
command: gem install bundler -v 2.1.4
|
64
|
+
|
53
65
|
- run:
|
54
66
|
name: Bundle Install
|
55
67
|
command: bundle install
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -204,7 +204,7 @@ variant = determinator.which_variant(
|
|
204
204
|
app_version: "1.2.3"
|
205
205
|
}
|
206
206
|
)
|
207
|
-
```
|
207
|
+
```
|
208
208
|
The `app_version` constraint for that flag needs to follow ruby gem version constraints. We support the following operators: `>, <, >=, <=, ~>`. For example:
|
209
209
|
`app_version: ">=1.2.0"`
|
210
210
|
|
@@ -220,6 +220,8 @@ Determinator.configure(retrieval: nil)
|
|
220
220
|
|
221
221
|
* Tag your rspec test with `:determinator_support`, so the `forced_determination` helper method will be available.
|
222
222
|
|
223
|
+
Please note, `RSpec::Determinator` mocks a determination _outcome_, not the process of choosing one. Set the `only_for` argument to be the properties you require for Determinator to return the specified outcome. At the moment this mock does not allow for the testing of the `id` or `guid` arguments (only the properties).
|
224
|
+
|
223
225
|
```ruby
|
224
226
|
RSpec.describe "something", :determinator_support do
|
225
227
|
|
@@ -251,6 +253,70 @@ end
|
|
251
253
|
|
252
254
|
* Check out [the specs for `RSpec::Determinator`](spec/rspec/determinator_spec.rb) to find out what you can do!
|
253
255
|
|
256
|
+
## Tracking
|
257
|
+
|
258
|
+
The library includes a middleware to track all determinations being made, allowing logging them at the end of the request
|
259
|
+
(including some useful request metrics).
|
260
|
+
|
261
|
+
To enable it, e.g. in Rails:
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
# config/application.rb
|
265
|
+
|
266
|
+
require 'determinator/tracking/rack/middleware'
|
267
|
+
|
268
|
+
# possibly near the top of your stack, in case other middlewares make determinations
|
269
|
+
config.middleware.use Determinator::Tracking::Rack::Middleware
|
270
|
+
```
|
271
|
+
|
272
|
+
or for Sidekiq:
|
273
|
+
|
274
|
+
```ruby
|
275
|
+
# config/initializers/sidekiq.rb
|
276
|
+
|
277
|
+
require 'determinator/tracking/sidekiq/middleware'
|
278
|
+
|
279
|
+
Sidekiq.configure_server do |config|
|
280
|
+
config.server_middleware do |chain|
|
281
|
+
chain.add Determinator::Tracking::Sidekiq::Middleware
|
282
|
+
end
|
283
|
+
end
|
284
|
+
```
|
285
|
+
|
286
|
+
```ruby
|
287
|
+
# config/initializers/determinator.rb
|
288
|
+
|
289
|
+
require 'determinator/tracking'
|
290
|
+
|
291
|
+
Determinator::Tracking.on_request do |r|
|
292
|
+
Rails.logger.info("tag=determinator_request type=#{r.type} request_time=#{r.time} error=#{r.error?} response_status=#{r.attributes[:status]} sidekiq_queue=#{r.attributes[:queue]}")
|
293
|
+
r.determinations.each do |d|
|
294
|
+
Rails.logger.info("tag=determination id=#{d.id} guid=#{d.guid} flag=#{d.feature_id} result=#{d.determination}")
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
# If using an APM, you can provide trace information on the request by providing a get_context hook: e.g.
|
299
|
+
|
300
|
+
Determinator::Tracking.get_context do
|
301
|
+
span = Datadog.tracer.active_root_span
|
302
|
+
return unless span
|
303
|
+
Determinator::Tracking::Context.new(
|
304
|
+
request_id: span.trace_id,
|
305
|
+
service: span.service,
|
306
|
+
resource: span.resource,
|
307
|
+
type: span.type,
|
308
|
+
meta: span.meta
|
309
|
+
)
|
310
|
+
end
|
311
|
+
```
|
312
|
+
|
313
|
+
NOTE: this is implemented by keeping the list of requests in a per-request thread-local variable, which means that determinations will only be tracked on the main thread.
|
314
|
+
|
315
|
+
If your application is spinning out worker threads, you should make the determinations in the main thread if possible; or collect them from your worker threads and track them in the main thread with
|
316
|
+
```
|
317
|
+
Determinator::Tracking.track(id, guid, feature, determination)
|
318
|
+
```
|
319
|
+
|
254
320
|
## Testing this library
|
255
321
|
|
256
322
|
This library makes use of the [Determinator Standard Tests](https://github.com/deliveroo/determinator-standard-tests) to ensure that it conforms to the same specification as determinator libraries in other languages. The standard tests can be updated to the latest ones available by updating the submodule:
|
data/determinator.gemspec
CHANGED
@@ -23,11 +23,12 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_runtime_dependency "faraday"
|
24
24
|
spec.add_runtime_dependency "semantic", "~> 1.6"
|
25
25
|
|
26
|
-
spec.add_development_dependency "bundler", "~> 1.
|
26
|
+
spec.add_development_dependency "bundler", "~> 2.1.4"
|
27
27
|
spec.add_development_dependency "rake", "~> 10.0"
|
28
28
|
spec.add_development_dependency "rspec", "~> 3.0"
|
29
29
|
spec.add_development_dependency "rspec-its", "~> 1.2"
|
30
30
|
spec.add_development_dependency "guard-rspec", "~> 4.7"
|
31
31
|
spec.add_development_dependency "factory_girl", "~> 4.8"
|
32
32
|
spec.add_development_dependency 'webmock'
|
33
|
+
spec.add_development_dependency "sidekiq"
|
33
34
|
end
|
data/lib/determinator.rb
CHANGED
@@ -6,6 +6,7 @@ require 'determinator/cache/fetch_wrapper'
|
|
6
6
|
require 'determinator/serializers/json'
|
7
7
|
require 'determinator/missing_response'
|
8
8
|
require 'determinator/error_response'
|
9
|
+
require 'determinator/tracking'
|
9
10
|
|
10
11
|
|
11
12
|
module Determinator
|
@@ -83,6 +84,7 @@ module Determinator
|
|
83
84
|
end
|
84
85
|
|
85
86
|
def notice_determination(id, guid, feature, determination)
|
87
|
+
Determinator::Tracking.track(id, guid, feature, determination)
|
86
88
|
return unless @determination_callback
|
87
89
|
@determination_callback.call(id, guid, feature, determination)
|
88
90
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'determinator/tracking/tracker'
|
2
|
+
require 'determinator/tracking/context'
|
3
|
+
|
4
|
+
module Determinator
|
5
|
+
module Tracking
|
6
|
+
class << self
|
7
|
+
def instance
|
8
|
+
Thread.current[:determinator_tracker]
|
9
|
+
end
|
10
|
+
|
11
|
+
def start!(type)
|
12
|
+
Thread.current[:determinator_tracker] = Tracker.new(type)
|
13
|
+
end
|
14
|
+
|
15
|
+
def finish!(error:, **attributes)
|
16
|
+
return false unless started?
|
17
|
+
request = instance.finish!(error: error, **attributes)
|
18
|
+
clear!
|
19
|
+
report(request)
|
20
|
+
request
|
21
|
+
end
|
22
|
+
|
23
|
+
def clear!
|
24
|
+
Thread.current[:determinator_tracker] = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def started?
|
28
|
+
!!instance
|
29
|
+
end
|
30
|
+
|
31
|
+
def track(id, guid, feature, determination)
|
32
|
+
return false unless started?
|
33
|
+
instance.track(id, guid, feature, determination)
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_request(&block)
|
37
|
+
@on_request = block
|
38
|
+
end
|
39
|
+
|
40
|
+
def report(request)
|
41
|
+
return unless @on_request
|
42
|
+
@on_request.call(request)
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_context(&block)
|
46
|
+
@get_context = block
|
47
|
+
end
|
48
|
+
|
49
|
+
def context
|
50
|
+
return unless @get_context
|
51
|
+
@get_context.call
|
52
|
+
rescue
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def clear_hooks!
|
57
|
+
@on_request = nil
|
58
|
+
@get_context = nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Determinator
|
2
|
+
module Tracking
|
3
|
+
class Context
|
4
|
+
attr_reader :request_id, :service, :resource
|
5
|
+
|
6
|
+
def initialize(request_id: nil, service: nil, resource: nil, type: nil, meta: {})
|
7
|
+
@request_id = request_id
|
8
|
+
@service = service
|
9
|
+
@resource = resource
|
10
|
+
@type = type
|
11
|
+
@meta = meta
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Determinator
|
2
|
+
module Tracking
|
3
|
+
class Determination
|
4
|
+
attr_reader :id, :guid, :feature_id, :determination
|
5
|
+
|
6
|
+
def initialize(id:, guid:, feature_id:, determination:)
|
7
|
+
@id = id
|
8
|
+
@guid = guid
|
9
|
+
@feature_id = feature_id
|
10
|
+
@determination = determination
|
11
|
+
end
|
12
|
+
|
13
|
+
def ==(other)
|
14
|
+
id == other.id && guid == other.guid && feature_id == other.feature_id && determination == other.determination
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'determinator/tracking'
|
2
|
+
|
3
|
+
module Determinator
|
4
|
+
module Tracking
|
5
|
+
module Rack
|
6
|
+
class Middleware
|
7
|
+
def initialize(app)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
Determinator::Tracking.start!(:rack)
|
13
|
+
status, headers, response = @app.call(env)
|
14
|
+
[status, headers, response]
|
15
|
+
rescue
|
16
|
+
error = true
|
17
|
+
raise
|
18
|
+
ensure
|
19
|
+
Determinator::Tracking.finish!(status: status, error: !!error)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Determinator
|
2
|
+
module Tracking
|
3
|
+
class Request
|
4
|
+
attr_reader :type, :time, :error, :attributes, :determinations, :context
|
5
|
+
|
6
|
+
def initialize(type:, time:, error:, attributes:, determinations:, context: nil)
|
7
|
+
@type = type
|
8
|
+
@time = time
|
9
|
+
@error = error
|
10
|
+
@attributes = attributes
|
11
|
+
@determinations = determinations
|
12
|
+
@context = context
|
13
|
+
end
|
14
|
+
|
15
|
+
def error?
|
16
|
+
error
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'determinator/tracking'
|
2
|
+
|
3
|
+
module Determinator
|
4
|
+
module Tracking
|
5
|
+
module Sidekiq
|
6
|
+
class Middleware
|
7
|
+
# @param [Object] worker the worker instance
|
8
|
+
# @param [Hash] job the full job payload
|
9
|
+
# * @see https://github.com/mperham/sidekiq/wiki/Job-Format
|
10
|
+
# @param [String] queue the name of the queue the job was pulled from
|
11
|
+
# @yield the next middleware in the chain or worker `perform` method
|
12
|
+
# @return [Void]
|
13
|
+
def call(worker, job, queue)
|
14
|
+
begin
|
15
|
+
Determinator::Tracking.start!(:sidekiq)
|
16
|
+
yield
|
17
|
+
rescue => ex
|
18
|
+
error = true
|
19
|
+
raise
|
20
|
+
ensure
|
21
|
+
Determinator::Tracking.finish!(queue: queue, error: !!error)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'determinator/tracking/determination'
|
2
|
+
require 'determinator/tracking/request'
|
3
|
+
|
4
|
+
module Determinator
|
5
|
+
module Tracking
|
6
|
+
class Tracker
|
7
|
+
attr_reader :type, :determinations
|
8
|
+
|
9
|
+
def initialize(type)
|
10
|
+
@determinations = []
|
11
|
+
@type = type
|
12
|
+
@start = now
|
13
|
+
end
|
14
|
+
|
15
|
+
def track(id, guid, feature, determination)
|
16
|
+
determinations << Determinator::Tracking::Determination.new(
|
17
|
+
id: id,
|
18
|
+
guid: guid,
|
19
|
+
feature_id: feature.identifier,
|
20
|
+
determination: determination
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def finish!(error:, **attributes)
|
25
|
+
request_time = now - @start
|
26
|
+
Determinator::Tracking::Request.new(
|
27
|
+
type: type,
|
28
|
+
time: request_time,
|
29
|
+
error: error,
|
30
|
+
attributes: attributes,
|
31
|
+
determinations: determinations,
|
32
|
+
context: Determinator::Tracking.context
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def now
|
39
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/determinator/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: determinator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- JP Hastings-Spital
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-03-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 2.1.4
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 2.1.4
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: sidekiq
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
139
153
|
description:
|
140
154
|
email:
|
141
155
|
- jp@deliveroo.co.uk
|
@@ -204,6 +218,13 @@ files:
|
|
204
218
|
- lib/determinator/retrieve/null_retriever.rb
|
205
219
|
- lib/determinator/serializers/json.rb
|
206
220
|
- lib/determinator/target_group.rb
|
221
|
+
- lib/determinator/tracking.rb
|
222
|
+
- lib/determinator/tracking/context.rb
|
223
|
+
- lib/determinator/tracking/determination.rb
|
224
|
+
- lib/determinator/tracking/rack/middleware.rb
|
225
|
+
- lib/determinator/tracking/request.rb
|
226
|
+
- lib/determinator/tracking/sidekiq/middleware.rb
|
227
|
+
- lib/determinator/tracking/tracker.rb
|
207
228
|
- lib/determinator/version.rb
|
208
229
|
- lib/rspec/determinator.rb
|
209
230
|
homepage: https://github.com/deliveroo/determinator
|
@@ -225,8 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
225
246
|
- !ruby/object:Gem::Version
|
226
247
|
version: '0'
|
227
248
|
requirements: []
|
228
|
-
|
229
|
-
rubygems_version: 2.7.9
|
249
|
+
rubygems_version: 3.0.3
|
230
250
|
signing_key:
|
231
251
|
specification_version: 4
|
232
252
|
summary: Determine which experiments and features a specific actor should see.
|