Packages
openfeature_elixir
0.1.0
OpenFeature is an open specification that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool.
Current section
Files
Jump to
Current section
Files
lib/providers/launchdarkly_provider.ex
defmodule OpenFeature.Providers.LaunchdarklyProvider do
@moduledoc """
A provider for Launchdarkly.
"""
@behaviour OpenFeature.Provider
alias OpenFeature.Providers.LaunchdarklyProvider
defstruct [:name, :sdk_key]
# def child_spec(opts) do
# %{
# id: OpenFeature.Providers.LaunchdarklyProvider.LDApi,
# start: {OpenFeature.Providers.LaunchdarklyProvider.LDApi, :init, [opts]},
# restart: :permanent,
# type: :worker
# }
# end
def new(sdk_key) do
%OpenFeature.Providers.LaunchdarklyProvider{
name: String.to_atom(UUID.uuid4()),
sdk_key: sdk_key
}
end
def set_name(%LaunchdarklyProvider{} = opts, name) do
Map.put(opts, :name, name)
end
def set_sdk_key(%LaunchdarklyProvider{} = opts, sdk_key) when is_binary(sdk_key) do
Map.put(opts, :sdk_key, sdk_key)
end
def wait_for_initialized(timeout, tag) do
wait_for_initialized(tag, System.os_time(:millisecond), false, timeout)
end
def wait_for_initialized(tag, started_at, false, timeout) do
elapsed = System.os_time(:millisecond) - started_at
inited = :ldclient.initialized(tag)
wait_for_initialized(tag, started_at, inited || elapsed > timeout, timeout)
end
def wait_for_initialized(_tag, _started_at, true, _timeout) do
:ok
end
def init(%LaunchdarklyProvider{sdk_key: sdk_key, name: nil}) do
init(%LaunchdarklyProvider{sdk_key: sdk_key, name: :default})
end
def init(%LaunchdarklyProvider{sdk_key: sdk_key, name: name}) do
case :ldclient.start_instance(
String.to_charlist(sdk_key),
name,
%{
:http_options => %{
:tls_options => :ldclient_config.tls_basic_options()
}
}
) do
:ok ->
:ok
{:error, :already_started, _} ->
:ok
end
wait_for_initialized(5000, name)
{:ok}
end
def get_boolean_value(
%OpenFeature.Providers.LaunchdarklyProvider{} = opts,
name,
default,
context
)
when is_boolean(default) do
get(opts.name || :default, name, default, ld_context_from_context(context))
end
def get_string_value(
%OpenFeature.Providers.LaunchdarklyProvider{} = opts,
name,
default,
context
)
when is_binary(default) do
get(opts.name || :default, name, default, ld_context_from_context(context))
end
defp get(pname, key, fallback, context) do
:ldclient.variation(key, context, fallback, pname)
end
defp ld_context_from_context(%OpenFeature.Context{} = context) do
:ldclient_context.new_from_map(
Map.merge(
%{
:key => context.key
},
context.body
)
)
end
end