defmodule Ravix.Documents.Session.Supervisor do
@moduledoc """
Supervisor for RavenDB Sessions
"""
alias Ravix.Documents.Session
alias Ravix.Documents.Session.State, as: SessionState
@spec start_link(any) :: :ignore | {:error, any} | {:ok, pid}
def start_link(store) do
children = [
{PartitionSupervisor, child_spec: DynamicSupervisor, name: supervisor_name(store)}
]
Supervisor.start_link(children, strategy: :one_for_one)
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(
{:via, PartitionSupervisor,
{supervisor_name(session_state.store), session_state.session_id}},
{Session, session_state}
)
end
@doc """
Closes a session for the informed store using the session pid or session_id
"""
@spec close_session(atom(), bitstring()) :: :ok | {:error, :not_found}
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(
{:via, PartitionSupervisor, {supervisor_name(store), session_id}},
pid
)
end
end
defp supervisor_name(store) do
:"#{store}.Sessions"
end
end