Packages
Official Split by Harness SDK for feature flags (a.k.a. Split FME)
Current section
Files
Jump to
Current section
Files
lib/split/rpc/fallback.ex
defmodule Split.RPC.Fallback do
@moduledoc """
This module is used to provide default values for all Splitd RPC calls.
When a call to Splitd fails, and the SDK was initialized with `fallback_enabled`,
the fallback values are returned instead of the error received from the socket.
"""
use Split.RPC.Opcodes
alias Split.RPC.Message
alias Split.Treatment
@doc """
Provides a default value for the given RPC message.
## Examples
iex> Fallback.fallback(%Message{o: 0x11})
{:ok, %Treatment{treatment: "control", label: "fallback treatment"}}
iex> Fallback.fallback(%Message{o: 0x13})
{:ok, %Treatment{treatment: "control", label: "fallback treatment", config: nil}}
iex> Fallback.fallback(%Message{
...> o: 0x12,
...> a: ["user_key", "bucketing_key", ["feature_1", "feature_2"], %{}]
...> })
{:ok,
%{
"feature_1" => %Treatment{treatment: "control", label: "fallback treatment"},
"feature_2" => %Treatment{treatment: "control", label: "fallback treatment"}
}}
iex> Fallback.fallback(%Message{o: 0x14, a: ["user_key", "bucketing_key", ["feature_a"], %{}]})
{:ok, %{"feature_a" => %Treatment{treatment: "control", label: "fallback treatment", config: nil}}}
iex> Fallback.fallback(%Message{o: 0xA1})
{:ok, nil}
iex> Fallback.fallback(%Message{o: 0xA2})
{:ok, []}
iex> Fallback.fallback(%Message{o: 0xA0})
{:ok, %{split_names: []}}
iex> Fallback.fallback(%Message{o: 0x80})
:ok
"""
@spec fallback(Message.t()) :: {:ok, map() | Treatment.t(), list(), nil} | :ok
def fallback(%Message{o: opcode})
when opcode in [@get_treatment_opcode, @get_treatment_with_config_opcode] do
{:ok, %Treatment{label: "fallback treatment"}}
end
def fallback(%Message{o: opcode, a: args})
when opcode in [@get_treatments_opcode, @get_treatments_with_config_opcode] do
feature_names = Enum.at(args, 2)
treatments =
Enum.reduce(feature_names, %{}, fn feature_name, acc ->
Map.put(acc, feature_name, %Treatment{label: "fallback treatment"})
end)
{:ok, treatments}
end
def fallback(%Message{o: @split_opcode}) do
{:ok, nil}
end
def fallback(%Message{o: @splits_opcode}) do
{:ok, []}
end
def fallback(%Message{o: @split_names_opcode}) do
{:ok, %{split_names: []}}
end
def fallback(%Message{o: @track_opcode}) do
:ok
end
end