Current section
Files
Jump to
Current section
Files
lib/hermes/server/session/supervisor.ex
defmodule Hermes.Server.Session.Supervisor do
@moduledoc false
use DynamicSupervisor
alias Hermes.Server.Session
@kind :session_supervisor
@doc """
Starts the session supervisor.
## Parameters
* `server` - The server module atom
## Returns
* `{:ok, pid}` - Supervisor started successfully
* `{:error, reason}` - Failed to start supervisor
## Examples
{:ok, _pid} = Session.Supervisor.start_link(MyServer)
"""
def start_link(opts \\ []) do
server = Keyword.fetch!(opts, :server)
registry = Keyword.get(opts, :registry, Hermes.Server.Registry)
name = registry.supervisor(@kind, server)
DynamicSupervisor.start_link(__MODULE__, server, name: name)
end
@doc """
Creates a new session for a client connection.
## Parameters
* `registry` - The registry module to use to retrieve processes names
* `server` - The server module atom
* `session_id` - Unique identifier for the session (typically from transport)
## Returns
* `{:ok, pid}` - Session created successfully
* `{:error, {:already_started, pid}}` - Session already exists
* `{:error, reason}` - Failed to create session
## Examples
# Create a new session for a client
{:ok, session_pid} = Session.Supervisor.create_session(MyRegistry, MyServer, "session-123")
# Attempting to create duplicate session
{:error, {:already_started, ^session_pid}} =
Session.Supervisor.create_session(MyRegistry, MyServer, "session-123")
"""
def create_session(registry \\ Hermes.Server.Registry, server, session_id) do
name = registry.supervisor(@kind, server)
session_name = registry.server_session(server, session_id)
DynamicSupervisor.start_child(
name,
{Session, session_id: session_id, name: session_name}
)
end
@doc """
Terminates a session and cleans up its resources.
## Parameters
* `registry` - The registry module to use to retrieve processes names
* `server` - The server module atom
* `session_id` - The session identifier to terminate
## Returns
* `:ok` - Session terminated successfully
* `{:error, :not_found}` - Session does not exist
## Examples
# Close an existing session
:ok = Session.Supervisor.close_session(MyRegistry, MyServer, "session-123")
# Attempting to close non-existent session
{:error, :not_found} = Session.Supervisor.close_session(MyRegistry, MyServer, "unknown")
"""
def close_session(registry \\ Hermes.Server.Registry, server, session_id)
when is_binary(session_id) do
name = registry.supervisor(@kind, server)
if pid = registry.whereis_server_session(server, session_id) do
DynamicSupervisor.terminate_child(name, pid)
else
{:error, :not_found}
end
end
@impl DynamicSupervisor
def init(_init_arg) do
DynamicSupervisor.init(strategy: :one_for_one)
end
end