README.md in determinator-0.12.0 vs README.md in determinator-0.12.1
- old
+ new
@@ -14,39 +14,55 @@
#### Getting help
For Deliveroo Employees:
-- Many people contribute to Determinator and Florence. We hang out in [this Slack channel](slack://channel?team=T03EUNC3F&id=C7437816J)
+- Many people contribute to Determinator and Florence. We hang out in [this Slack channel](https://deliveroo.slack.com/app_redirect?channel=florence_wg)
- [This JIRA board](https://deliveroo.atlassian.net/secure/RapidBoard.jspa?rapidView=156) covers pieces of work that are planned or in-flight
- [This Workplace group](https://deliveroo.facebook.com/groups/1893254264328414/) holds more general discussions about the Florence ecosystem
At the moment we can only promise support for Determinator within Deliveroo, but if you add [issues to this github repo](https://github.com/deliveroo/determinator/issues) we'll try and help if we can!
-## Usage
+## Basic Use
-Once [set up](#installation), determinator can be used to determine whether a **feature flag** or **experiment** is on or off for the current user and, for experiments, which **variant** they should see.
+Once [set up](#installation), determinator can be used to determine whether a **feature flag** or **experiment** is on or off for the current actor (or user) and, for experiments, which **variant** they should see.
```ruby
-# Feature flags
+# Feature flags: the basics
+Determinator.instance.feature_flag_on?(:my_feature_name, id: 'some user')
+# => true
+Determinator.instance.feature_flag_on?(:my_feature_name, id: 'another user')
+# => false
+
+# A handy short cut…
+def determinator
+ # See the urther Usage section below for a handy shorthand which means ID
+ # and GUID don't need to be specified every time you need a determination.
+end
+
+# Which means you can also do:
if determinator.feature_flag_on?(:my_feature_name)
# Show the feature
end
# Experiments
case determinator.which_variant(:my_experiment_name)
+when false
+ # This actor isn't in a target group for this experiment
when 'control'
# Do nothing different
when 'sloths'
# Show some sloth pictures
when 'velociraptors'
# RUN!
end
```
-Feature flags and experiments can be targeted to specific actors by specifying actor properties (which must match the constraints defined in the feature).
+Please note that Determinator requires an identifier for your actor — either an ID (when they are logged in, eg. a user id), or a globally unique id (GUID) that identifies them across sessions (which would normally be storied in a cookie or in a long-lived session store).
+Feature flags and experiments can be limited to actors with specific properties by specifying them when (which must match the constraints defined in the feature).
+
```ruby
# Targeting specific actors
variant = determinator.which_variant(
:my_experiment_name,
properties: {
@@ -57,17 +73,13 @@
Writing tests? Check out the [Local development](docs/local_development.md) docs to see examples of `RSpec::Determinator` to help you mock your Feature Flags and Experiments.
## Installation
-Determinator requires your application to be subscribed to the a `features` topic via Routemaster.
+Determinator requires a initialiser block somewhere in your application's boot process, it might look something like this:
-The drain must expire the routemaster cache on receipt of events, `Routemaster::Drain::CacheBusting.new` or better.
-
-Check the example Rails app in `examples` for more information on how to make use of this gem.
-
-```
+```ruby
# config/initializers/determinator.rb
require 'determinator/retrieve/routemaster'
Determinator.configure(
retrieval: Determinator::Retrieve::Routemaster.new(
@@ -77,40 +89,92 @@
errors: -> error { NewRelic::Agent.notice_error(error) },
missing_features: -> feature_name { STATSD.increment 'determinator.missing_feature', tags: ["feature:#{name}"] }
)
```
-### Using Determinator in RSpec
+This configures the `Determinator.instance` with:
-* Include those lines in `spec_helper.rb`.
+- What **retrieval** mechanism should be used to get feature details
+- (optional) How **errors** should be reported
+- (optional) How **missing features** should be monitored (as they indicate something's up with your code or your set up!)
+You may also want to configure a `determinator` helper method inside your web request scope, see below for more information.
+## Further Usage
+
+Once this is done you can ask for a determination like this:
+
+```ruby
+# Anywhere in your application:
+variant = Determinator.instance.which_variant?(
+ :my_experiment_name,
+ id: 123,
+ guid: 'anonymous id',
+ properties: {
+ employee: true,
+ using_top_level_domain: 'uk'
+ }
+)
```
-require 'rspec/determinator'
-Determinator.configure(retrieval: nil)
+Or, if you're within a web request, you might want to use a shorthand, and let determinator remember the ID, GUID and any properties which will be true. The following will have the same effect:
+```ruby
+# Somewhere inside your request's scope:
+def determinator
+ @determinator ||= Determinator.instance.for_actor(
+ id: 123,
+ guid: 'anonymous id',
+ default_properties: {
+ employee: true,
+ using_top_level_domain: 'uk'
+ }
+ )
+end
+
+# Anywhere in your requests' scope:
+determinator.which_variant(:my_experiment_name)
```
-* Tag your rspec test with `:determinator_support`, so `forced_determination` helper method will be available.
+Check the example Rails app in the `examples` directory for more information on how to make use of this gem.
+### Routemaster
+Determinator's [Routemaster](https://github.com/deliveroo/routemaster) integration requires your application to be subscribed to the a `features` topic.
+
+The drain must expire the routemaster cache on receipt of events, making use of `Routemaster::Drain::CacheBusting.new` or similar is recommended.
+
+### Using Determinator in RSpec
+
+* Include the `spec_helper.rb`.
+
+```ruby
+require 'rspec/determinator'
+
+Determinator.configure(retrieval: nil)
```
+* Tag your rspec test with `:determinator_support`, so the `forced_determination` helper method will be available.
+
+```ruby
RSpec.describe "something", :determinator_support do
context "something" do
forced_determination(:my_feature_flag, true)
forced_determination(:my_experiment, "variant_a")
+ forced_determination(:my_lazyexperiment, :some_lazy_variable)
+ let(:some_lazy_variable) { 'variant_b' }
it "uses forced_determination" do
expect(Determinator.instance.feature_flag_on?(:my_feature_flag)).to eq(true)
expect(Determinator.instance.which_variant(:my_experiment)).to eq("variant_a")
+ expect(Determinator.instance.which_variant(:my_lazy_experiment)).to eq("variant_b")
end
end
end
-
```
+
+* Check out [the specs for `RSpec::Determinator`](spec/rspec/determinator_spec.rb) to find out what you can do!
### Retrieval Cache
Determinator will function fully without a retrieval_cache set, although Determinator will produce 1 Redis query for every determination. By setting a `retrieval_cache` as an instance of `ActiveSupport::Cache::MemoryStore` (or equivalent) this can be reduced per application instance. This cache is not expired so *must* have a `expires_in` set, ideally to a short amount of time.