Current section

Files

Jump to
commanded lib commanded application config.ex
Raw

lib/commanded/application/config.ex

defmodule Commanded.Application.Config do
@moduledoc false
use GenServer
def start_link(_opts) do
GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
end
def associate(pid, application, value) when is_pid(pid) and is_atom(application) do
GenServer.call(__MODULE__, {:associate, pid, application, value})
end
def get(application, setting) when is_atom(application) and is_atom(setting) do
application |> lookup() |> Keyword.get(setting)
end
@doc """
Put a value into the application's config. This is test induced damage and you
probably shouldn't be using it.
"""
def __put__(application, setting, value) when is_atom(application) and is_atom(setting) do
GenServer.call(__MODULE__, {:put, application, setting, value})
end
@impl GenServer
def init(:ok) do
table = :ets.new(__MODULE__, [:named_table, read_concurrency: true])
{:ok, table}
end
@impl GenServer
def handle_call({:associate, pid, application, config}, _from, table) do
ref = Process.monitor(pid)
true = :ets.insert(table, {application, pid, ref, config})
{:reply, :ok, table}
end
@impl GenServer
def handle_call({:put, application, settings, value}, _from, table) do
config =
lookup(application)
|> Keyword.put(settings, value)
true = :ets.update_element(table, application, {4, config})
{:reply, :ok, table}
end
@impl GenServer
def handle_info({:DOWN, ref, _type, pid, _reason}, table) do
[[application]] = :ets.match(table, {:"$1", pid, ref, :_})
:ets.delete(table, application)
{:noreply, table}
end
defp lookup(application) do
:ets.lookup_element(__MODULE__, application, 4)
rescue
ArgumentError ->
raise "could not lookup #{inspect(application)} because it was not started or it does not exist"
end
end