defmodule Tai.Settings do @moduledoc """ Run time settings """ use GenServer alias __MODULE__ defmodule State do @enforce_keys ~w[send_orders name]a defstruct ~w[send_orders name]a end @type t :: %Settings{ send_orders: boolean } @enforce_keys ~w[send_orders]a defstruct ~w[send_orders]a @default_id :default def start_link(opts) do config = Keyword.fetch!(opts, :config) id = Keyword.get(opts, :id, @default_id) name = process_name(id) state = %State{send_orders: config.send_orders, name: name} GenServer.start_link(__MODULE__, state, name: name) end def process_name(id), do: :"#{__MODULE__}_#{id}" def disable_send_orders!(id \\ @default_id) do id |> process_name() |> GenServer.call({:set_send_orders, false}) end def enable_send_orders!(id \\ @default_id) do id |> process_name() |> GenServer.call({:set_send_orders, true}) end def send_orders?(id \\ @default_id) do [{:send_orders, send_orders}] = id |> process_name() |> :ets.lookup(:send_orders) send_orders end def all(id \\ @default_id) do %Settings{send_orders: send_orders?(id)} end @impl true def init(state) do { :ok, state, {:continue, :create_ets_table} } end @impl true def handle_continue(:create_ets_table, state) do create_ets_table(state.name) upsert_items(state) {:noreply, state} end @impl true def handle_call({:set_send_orders, val}, _from, state) do state.name |> :ets.insert({:send_orders, val}) {:reply, :ok, state} end defp create_ets_table(name) do :ets.new(name, [:set, :protected, :named_table]) end defp upsert_items(state) do state |> Map.to_list() |> Enum.filter(fn {k, _} -> k != :__struct__ end) |> Enum.each(fn item -> :ets.insert(state.name, item) end) end end