View Source SplitClient
Elixir client to use for Split.io feature flag service https://www.split.io/
installation
Installation
If available in Hex, the package can be installed
by adding split_client
to your list of dependencies in mix.exs
:
def deps do
[
{:split_client, "~> 0.1.0"}
]
end
configuration
Configuration
evaluator-configuration
Evaluator Configuration
The Split.io Evaluator sits in your infrastructure between the Split.io servers. It provides a REST API for accessing Split.io data and is meant to be used in cases where Split.io has not created an SDK for a specific language like Elixir.
In order for your application to access Split.io feature flag data you'll need to configure
how to access your instance of Split.io Evaluator. You'll need to configure the evaluator_auth_token
and the
evaluator_url
.
In production you'll need to have your config access these environment variables. You could
do it like this in config/prod.exs
:
config :split_client, evaluator_auth_token: System.fetch_env!("SPLIT_EVALUATOR_AUTH_TOKEN")
config :split_client, evaluator_url: System.fetch_env!("SPLIT_EVALUATOR_URL")
local-feature-development
Local Feature Development
When you're developing features locally you don't want to toggle split treatments
in the Split.io web interface. The web interface changes things globally across
your infrastructure and isn't meant for testing changes on your local machine.
Instead you'll make changes in a local YAML file. Add this to your config/dev.exs
config :split_client, data_source: SplitClient.DataSourceYAML
By default the SplitClient
will expect this YAML file to live in the root of
your project and be called split.yml
. You can change this in config/dev.exs
with
config :split_client, split_file: "my/file/path.yml"
The YAML file should follow a format similar to this:
# - feature_name:
# treatment: "treatment_applied_to_this_entry"
# keys: ["single_key_or_list", "other_key_same_treatment"]
# traffic_type: "customer"
# config: "{\"desc\" : \"this applies only to ON treatment\"}"
#
# Note that the "treatment" and "traffic_type" keys are mandatory, but both "keys" and
# "config" are optional. If "keys" are omitted they will be a fallback for when a passed key
# doesn't match
# Note that the config is JSON
# Note that `keys` can be a single key or a list of keys
# Not the attributes and bucketing_keys are ignored when using YAML stub
- my_feature:
treatment: "on"
keys: "mock_user_id"
traffic_type: "customer"
config: "{\"desc\" : \"this applies only to ON treatment\"}"
- some_other_feature:
treatment: "off"
traffic_type: "customer"
- my_feature:
treatment: "off"
traffic_type: "customer"
caching-and-treatment-updates
Caching and Treatment Updates
Out of the box the SplitClient will automatically cache treatments with a 1 minute expiration.
You can change this by setting the :cache_ttl
to a number of milliseconds of your choosing
config :split_client, :cache_ttl, :timer.seconds(1)
test-configuration
Test Configuration
Normally you want your application to share a global cache of Split.io
data. This isn't the case when you are running tests. In the testing
environment you want each test to have its own isolated set of
Split data so that each test can be run concurrently. To ensure this
you can swap out the regular Treatments server for a Sandbox in
config/test.exs
config :split_client, :treatments_server, SplitClient.Sandbox
split-io-glossary
Split.io Glossary
In Split.io nomenclature a "Split" is equivalent to a "Feature Flag"
function-arguments
Function Arguments
key
ormatching_key
- Some kind of unique identifier to identify the user, customer, account, etc. A non-match results in default/control treatmentsplit_name
- The name of the Split to get the treatment for (e.g."shiny_feature"
)traffic_type
- The Split.io Traffic Type the splits are associated with (e.g."user"
,"customer"
,"account"
, etc)
function-options
Function Options
:attributes
- AMap
of custom attributes to target on (e.g.%{plan_type: "premium", paying_customer: true}
)See also: Target Customer Attributes
:bucketing_key
- Which part of the distribution to look for a treatment out of 100% (e.g."20-39"
)See also: Treatment Order
testing
Testing
Normally you want your application to share a global cache of Split.io data. This isn't the case when you are running tests. In the testing environment you want each test to have its own isolated set of Split data so that each test can be run concurrently. A little bit of setup in each test file will be required.
import SplitClient.Testing
setup :setup_split_client
First, you'll want to import the SplitClient.Testing
module and execute setup_split_client/1
before
every test. This will give each test it's own Split environment that won't be affected by any
other tests running in parallel.
Second, you'll want to create your Split definitions. This can be the same for all tests in the file or vary per test. These definitions follow the same rules as the ones in Local Feature Development
setup do
create_splits([
%{
"my_feature" => %{
treatment: "on",
keys: "mock_user_id",
traffic_type: "customer"
}
},
%{
"my_feature" => %{
treatment: "off",
traffic_type: "customer"
}
}
])
:ok
end
create_splits/1
takes list of maps. Each map should have
one key for the split_name which has as its value a map
with the treatment information.
multi-process-collaboration
Multi-process Collaboration
Explicit Allowance
You may have a process in your application that is using Split.io data
that is outside of the test process. In this case you'll need to
explicitally associate the test process with the outside process so that
the isolated Split data can be accessed. You can use SplitClient.Sandbox.allow/2
for this.
test "test a thing" do
task =
Task.async(fn ->
assert feature_a("mock_user_id") == "New Hotness"
end)
Sandbox.allow(self(), task.pid)
Task.await(task)
end
Async False
Sometimes there are unfortunate circumstances where you do not own the process
accessing your Split.io data or the process is otherwise unnamed and unaccessible.
In these circumstances you'll be relegated to making your test async: false
to
ensure that the test is predictable and only accesses Split data that it's supposed to
contributing
Contributing
If you are making improvements to this package there will be some setup involved.
accessing-a-split-io-evaluator-instance
Accessing a Split.io Evaluator Instance
You'll need to add environment variables of SPLIT_EVALUATOR_AUTH_TOKEN
and SPLIT_EVALUATOR_URL
if you would like to test against a real Evaluator instance.
You'll also need to make the Evaluator your datasource in the dev environment.
Update to config/dev.exs
to include:
config :split_client, :data_source, SplitClient.Boundary.Evaluator
documentation
Documentation
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/split_client.