Packages

A feature toggle library using redis. It allows to roll out to users based on a percentage of users or alternatively to a set of users or user ids

Current section

Files

Jump to
molasses lib molasses.ex
Raw

lib/molasses.ex

defmodule Molasses do
alias Molasses.StorageAdapter.Redis
def is_active(client, key) do
case get_feature(client, key) do
{:error, _} -> false
%{active: false} -> false
%{active: true,percentage: 100, users: []} -> true
%{active: true,percentage: 100} -> false
%{active: true,percentage: _} -> false
end
end
def is_active(client, key, id) do
case get_feature(client, key) do
{:error, _} -> false
%{active: false} -> false
%{active: true,percentage: 100, users: []} -> true
%{active: true,percentage: 100, users: users} -> Enum.member?(users, id)
%{active: true,percentage: percentage} when is_integer(id) ->
value = Integer.to_string(id) |> :erlang.crc32 |> rem(100) |> abs
value <= percentage
%{active: true,percentage: percentage} when is_bitstring(id) ->
value = id |> :erlang.crc32 |> rem(100) |> abs
value <= percentage
end
end
def get_feature(client, key) do
case Redis.get(client, key) do
:undefined -> {:error, "failure"}
result ->
[active, percentage, users] = String.split(result, "|")
%{
name: key,
active: return_bool(active),
percentage: String.to_integer(percentage),
users: convert_to_list(users),
}
end
end
def convert_to_list(""), do: []
def convert_to_list(non_empty_string) do
non_empty_string
|> String.split(",")
|> Enum.map(fn (x) -> prepare_value(x) end)
end
def prepare_value(x) do
y = try do
String.to_integer(x)
rescue
_ -> x
end
y
end
def return_bool("true"), do: true
def return_bool("false"), do: false
def activate(client, key) do
Redis.set(client, key, "true|100|")
end
def activate(client, key, percentage) when is_integer(percentage) do
Redis.set(client, key, "true|#{percentage}|")
end
def activate(client, key, users) when is_list(users) do
activated_users = Enum.join(users,",")
Redis.set(client, key, "true|100|#{activated_users}")
end
def activate(client, key, group) do
Redis.set(client, key, "true|100|#{group}")
end
def deactivate(client, key) do
Redis.set(client, key, "false|0|")
end
end