defmodule Ravix.Documents.Session.Supervisor do @moduledoc """ Supervisor for RavenDB Sessions """ use DynamicSupervisor alias Ravix.Documents.Session alias Ravix.Documents.Session.State, as: SessionState def init(init_arg) do DynamicSupervisor.init( strategy: :one_for_one, extra_arguments: [init_arg] ) end @spec start_link(any) :: :ignore | {:error, any} | {:ok, pid} def start_link(store) do DynamicSupervisor.start_link(__MODULE__, %{}, name: supervisor_name(store)) end @doc """ Creates a session with the informed initial state """ @spec create_session(SessionState.t()) :: :ignore | {:error, any} | {:ok, pid} | {:ok, pid, any} def create_session(%SessionState{} = session_state) do session_state = session_state |> SessionState.update_last_session_call() DynamicSupervisor.start_child(supervisor_name(session_state.store), {Session, session_state}) end @doc """ Closes a session for the informed store using the session pid or session_id """ @spec close_session(atom(), pid | bitstring()) :: :ok | {:error, :not_found} def close_session(store, pid) when is_pid(pid) do DynamicSupervisor.terminate_child(supervisor_name(store), pid) end def close_session(store, session_id) do case Registry.lookup(:sessions, session_id) do [] -> {:error, :not_found} sessions -> {pid, _} = sessions |> Enum.at(0) DynamicSupervisor.terminate_child(supervisor_name(store), pid) end end defp supervisor_name(store) do :"#{store}.Sessions" end end