Current section
Files
Jump to
Current section
Files
lib/open_feature/store.ex
defmodule OpenFeature.Store do
@moduledoc false
use GenServer
alias OpenFeature.Provider
alias OpenFeature.Provider.NoOp
alias OpenFeature.Types
@providers_table :open_feature_store_providers
@context_table :open_feature_store_context
@spec start_link(Keyword.t()) :: GenServer.on_start()
def start_link(opts) do
name = Keyword.get(opts, :name, __MODULE__)
GenServer.start_link(__MODULE__, :ok, name: name)
end
@spec set_provider(domain :: Types.domain(), provider :: Provider.t()) :: :ok
def set_provider(domain, provider) do
:ets.insert(@providers_table, {domain, provider})
:ok
end
@spec get_provider(domain :: Types.domain()) :: Provider.t()
def get_provider(domain) do
case :ets.lookup(@providers_table, domain) do
[{^domain, provider}] -> provider
[] -> %NoOp{}
end
end
@spec list_providers() :: [Provider.t()]
def list_providers do
@providers_table
|> :ets.tab2list()
|> Enum.map(fn {_, provider} -> provider end)
|> Enum.uniq()
end
@spec clear_providers() :: :ok
def clear_providers do
:ets.delete_all_objects(@providers_table)
:ets.insert(@providers_table, {"default", %NoOp{}})
:ok
end
@spec set_context(context :: Types.context()) :: :ok
def set_context(context) do
:ets.insert(@context_table, {:context, context})
:ok
end
@spec get_context() :: Types.context()
def get_context do
case :ets.lookup(@context_table, :context) do
[{:context, context}] -> context
[] -> %{}
end
end
@impl true
def init(:ok) do
:ets.new(@providers_table, [:named_table, :set, :public])
:ets.new(@context_table, [:named_table, :set, :public])
:ets.insert(@providers_table, {"default", %NoOp{state: :ready}})
:ets.insert(@context_table, {:context, %{}})
{:ok, nil, :hibernate}
end
end