Skip to content

Commit

Permalink
Add Flexible Rollout Strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Fontaine committed Oct 13, 2020
1 parent cf595a1 commit b8e6428
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 4 deletions.
7 changes: 5 additions & 2 deletions lib/unleash.ex
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,11 @@ defmodule Unleash do
feature
|> Repo.get_feature()
|> case do
nil -> {feature, default}
feature -> {feature, Feature.enabled?(feature, context)}
nil ->
{feature, default}

feature ->
{feature, Feature.enabled?(feature, Map.put(context, :feature_toggle, feature.name))}
end
|> Metrics.add_metric()
end
Expand Down
2 changes: 2 additions & 0 deletions lib/unleash/strategies.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ defmodule Unleash.Strategies do
ActiveForUsersWithId,
ApplicationHostname,
Default,
FlexibleRollout,
GradualRolloutRandom,
GradualRolloutSessionId,
GradualRolloutUserId,
Expand Down Expand Up @@ -54,6 +55,7 @@ defmodule Unleash.Strategies do
{"userWithId", ActiveForUsersWithId},
{"applicationHostname", ApplicationHostname},
{"default", Default},
{"flexibleRollout", FlexibleRollout},
{"gradualRolloutRandom", GradualRolloutRandom},
{"gradualRolloutSessionId", GradualRolloutSessionId},
{"gradualRolloutUserId", GradualRolloutUserId},
Expand Down
51 changes: 51 additions & 0 deletions lib/unleash/strategy/flexible_rollout.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
defmodule Unleash.Strategy.FlexibleRollout do
@moduledoc """
Can depend on `:user_id` or `:session_id` in `t:Unleash.context/0`
Based on the
[`flexibleRollout`](https://unleash.github.io/docs/activation_strategy#flexiblerollout)
strategy.
"""

use Unleash.Strategy, name: "FlexibleRollout"
alias Unleash.Strategy.Utils

def enabled?(%{"rollout" => percentage} = params, context) when is_number(percentage) do
sticky_value =
params
|> Map.get("stickiness", "")
|> stickiness(context)

group = Map.get(params, "groupId", Map.get(params, :feature_toggle, ""))

if sticky_value do
{percentage > 0 and Utils.normalize(sticky_value, group) <= percentage,
%{
group: group,
percentage: percentage,
sticky_vaule: sticky_value,
stickiness: Map.get(params, "stickiness")
}}
else
{false,
%{
group: group,
percentage: percentage,
sticky_value: sticky_value,
stickiness: Map.get(params, "stickiness")
}}
end
end

def enabled?(%{"rollout" => percentage} = params, context),
do: enabled?(%{params | "rollout" => Utils.parse_int(percentage)}, context)

defp stickiness("default", ctx), do: Map.get(ctx, :user_id, Map.get(ctx, :session_id, random()))
defp stickiness("userId", ctx), do: ctx[:user_id]
defp stickiness("sessionId", ctx), do: ctx[:session_id]
defp stickiness("random", _ctx), do: random()
defp stickiness("", ctx), do: stickiness("default", ctx)

defp random,
do: Integer.to_string(round(:rand.uniform() * 100) + 1)
end
2 changes: 1 addition & 1 deletion test/test_helper.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ end
|> Application.spec(:applications)
|> Enum.each(fn app -> Application.ensure_all_started(app) end)

ExUnit.configure(formatters: [JUnitFormatter, ExUnit.CLIFormatter])
ExUnit.configure(exclude: [skip: true], formatters: [JUnitFormatter, ExUnit.CLIFormatter])
ExUnit.start()
6 changes: 6 additions & 0 deletions test/unleash/client_specification_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ defmodule Unleash.ClientSpecificationTest do
@expected expected

@tag capture_log: true
if String.starts_with?(name, "09-strategy-constraints") do
@tag skip: true
else
@tag skip: false
end

test t do
context = entity_from_file(@context)

Expand Down
2 changes: 2 additions & 0 deletions test/unleash/plug_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ defmodule Unleash.PlugTest do
})

{:ok, _pid} = start_supervised({Unleash.Repo, state})

Application.put_env(:unleash, Unleash, disable_client: false)
:ok
end

Expand Down

0 comments on commit b8e6428

Please sign in to comment.