determinator 0.7.0 → 0.8.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
  SHA1:
3
- metadata.gz: 066363028ac1046f4d723b50c600c4f32482573e
4
- data.tar.gz: 9335a928b7c7ff5bc090fea102eaee6de44b335a
3
+ metadata.gz: b61e11a6498a8925acd9afe2f044ee454a0b155d
4
+ data.tar.gz: 033893ae1248afd025503413daebc2a0dd953a66
5
5
  SHA512:
6
- metadata.gz: b2160f41cf9f742948933bfae8fca2f64e6c051e7bfc4320f04148e47fbc78f1bf9b55a258fb8cd16e640a05197fc8c866881597a682041e97e0d9d526c0ccee
7
- data.tar.gz: fb1501b19164f5a70260930c32828a45ba31f39c6610c2cc4c792e309e53ed6e735dd776fbcd7b8bfbd74b34410d83c55d061a6a08fd75721d9e7f7aa43892e5
6
+ metadata.gz: 3f1abc324ad0a963d67d82fabdc35a49ea8149bd6a8718e2ece520a5b07ae7d101a4234455ae82e1ede5c76f1db8b5d96760440330c6be3dbe41836a5253759e
7
+ data.tar.gz: 500c7ec60e1dd4e08764dc3d0d30dc60cd0be635e4b42b8188b5363a0f37690a3984a6a0c109ee3ada8976931c5551678f48f4e2dabc52d82c97dfac65d2f56d
@@ -3,5 +3,6 @@ require 'determinator/retrieve/routemaster'
3
3
  Determinator.configure(
4
4
  retrieval: Determinator::Retrieve::Routemaster.new(
5
5
  discovery_url: 'https://florence.dev/'
6
+ retrieval_cache: ActiveSupport::Cache::MemoryStore.new(expires_in: 1.minute)
6
7
  )
7
8
  )
@@ -0,0 +1,5 @@
1
+ class NullCache
2
+ def fetch(name)
3
+ yield
4
+ end
5
+ end
@@ -2,6 +2,7 @@ require 'uri'
2
2
  require 'routemaster/drain/caching'
3
3
  require 'routemaster/responses/hateoas_response'
4
4
  require 'determinator/retrieve/routemaster_feature_id_cache_warmer'
5
+ require 'determinator/retrieve/null_cache'
5
6
 
6
7
  module Determinator
7
8
  module Retrieve
@@ -22,23 +23,52 @@ module Determinator
22
23
  CALLBACK_PATH = (URI.parse(ENV['ROUTEMASTER_CALLBACK_URL']).path rescue '/events').freeze
23
24
 
24
25
  # @param :discovery_url [String] The bootstrap URL of the instance of Florence which defines Features.
25
- def initialize(discovery_url:)
26
+ def initialize(discovery_url:, retrieval_cache: NullCache.new)
26
27
  client = ::Routemaster::APIClient.new(
27
28
  response_class: ::Routemaster::Responses::HateoasResponse
28
29
  )
29
- @routemaster = client.discover(discovery_url)
30
+ @retrieval_cache = retrieval_cache
31
+ @actor_service = client.discover(discovery_url)
30
32
  @routemaster_app = ::Routemaster::Drain::Caching.new(
31
33
  siphon_events: { 'features' => RoutemasterFeatureIdCacheWarmer }
32
34
  )
33
35
  end
34
36
 
35
37
  def retrieve(feature_name)
36
- key = self.class.index_cache_key(feature_name)
37
- feature_id = ::Routemaster::Config.cache_redis.get(key)
38
- return unless feature_id
38
+ cached_feature_lookup(feature_name) do
39
+ key = self.class.index_cache_key(feature_name)
40
+ feature_id = ::Routemaster::Config.cache_redis.get(key)
41
+ return unless feature_id
42
+ @actor_service.feature.show(feature_id)
43
+ end
44
+ rescue ::Routemaster::Errors::ResourceNotFound
45
+ nil
46
+ end
47
+
48
+ # Automatically configures the rails router to listen for Features with routemaster
49
+ #
50
+ # @param route_mapper [ActionDispatch::Routing::Mapper] The rails mapper, 'self' within the `routes.draw` block
51
+ def configure_rails_router(route_mapper)
52
+ route_mapper.mount routemaster_app, at: CALLBACK_PATH
53
+ end
54
+
55
+ def self.index_cache_key(feature_name)
56
+ "determinator_index:#{feature_name}"
57
+ end
58
+
59
+ def self.lookup_cache_key(feature_name)
60
+ "determinator_cache:#{feature_name}"
61
+ end
39
62
 
40
- obj = @routemaster.feature.show(feature_id)
63
+ private
41
64
 
65
+ def cached_feature_lookup(feature_name)
66
+ build_feature_from_api_response(
67
+ @retrieval_cache.fetch(self.class.lookup_cache_key(feature_name)){ yield }
68
+ )
69
+ end
70
+
71
+ def build_feature_from_api_response(obj)
42
72
  Feature.new(
43
73
  name: obj.body.name,
44
74
  identifier: obj.body.identifier,
@@ -56,19 +86,6 @@ module Determinator
56
86
  },
57
87
  winning_variant: obj.body.winning_variant,
58
88
  )
59
- rescue ::Routemaster::Errors::ResourceNotFound
60
- nil
61
- end
62
-
63
- # Automatically configures the rails router to listen for Features with routemaster
64
- #
65
- # @param route_mapper [ActionDispatch::Routing::Mapper] The rails mapper, 'self' within the `routes.draw` block
66
- def configure_rails_router(route_mapper)
67
- route_mapper.mount routemaster_app, at: CALLBACK_PATH
68
- end
69
-
70
- def self.index_cache_key(feature_name)
71
- "determinator_index:#{feature_name}"
72
89
  end
73
90
  end
74
91
  end
@@ -1,3 +1,3 @@
1
1
  module Determinator
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -0,0 +1,48 @@
1
+ module RSpec
2
+ module Determinator
3
+ def self.included(by)
4
+ by.extend(DSL)
5
+
6
+ by.let(:fake_determinator) { FakeControl.new }
7
+ by.before do
8
+ allow(Determinator::Control).to receive(:new).and_return(fake_determinator)
9
+ end
10
+ end
11
+
12
+ module DSL
13
+ def forced_determination(name, result, only_for: nil)
14
+ before do
15
+ fake_determinator.mock_result(
16
+ name,
17
+ result,
18
+ only_for: only_for
19
+ )
20
+ end
21
+ end
22
+ end
23
+
24
+ class FakeControl
25
+ def initialize
26
+ @mocked_results = {}
27
+ end
28
+
29
+ def mock_result(name, result, only_for: nil)
30
+ @mocked_results[name.to_s][only_for || {}] = result
31
+ end
32
+
33
+ def fake_determinate(name, id: nil, guid: nil, constraints: {})
34
+ constraints[:id] = id if id
35
+ constraints[:guid] = guid if guid
36
+
37
+ return false unless @mocked_results[name.to_s].has_key?(constraints)
38
+ @mocked_results[name.to_s][constraints]
39
+ end
40
+ alias_method :feature_flag_on?, :fake_determinate
41
+ alias_method :which_variant, :fake_determinate
42
+ end
43
+ end
44
+ end
45
+
46
+ RSpec.configure do |conf|
47
+ conf.include RSpec::Determinator, :determinator_support
48
+ end
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: 0.7.0
4
+ version: 0.8.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: 2017-07-11 00:00:00.000000000 Z
11
+ date: 2017-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: routemaster-drain
@@ -177,11 +177,13 @@ files:
177
177
  - lib/determinator/actor_control.rb
178
178
  - lib/determinator/control.rb
179
179
  - lib/determinator/feature.rb
180
+ - lib/determinator/retrieve/null_cache.rb
180
181
  - lib/determinator/retrieve/null_retriever.rb
181
182
  - lib/determinator/retrieve/routemaster.rb
182
183
  - lib/determinator/retrieve/routemaster_feature_id_cache_warmer.rb
183
184
  - lib/determinator/target_group.rb
184
185
  - lib/determinator/version.rb
186
+ - lib/rspec/determinator.rb
185
187
  homepage: https://github.com/deliveroo/determinator
186
188
  licenses:
187
189
  - MIT
@@ -207,4 +209,3 @@ signing_key:
207
209
  specification_version: 4
208
210
  summary: Determine which experiments and features a specific actor should see.
209
211
  test_files: []
210
- has_rdoc: