Snakepit.Bridge.SessionStore (snakepit v0.1.2)

Centralized session store using ETS for high-performance session management.

This GenServer manages a centralized ETS table for storing session data, providing CRUD operations, TTL-based expiration, and automatic cleanup. The store is designed for high concurrency with optimized ETS settings.

Summary

Functions

Returns a specification to start this module under a supervisor.

Manually triggers cleanup of expired sessions.

Creates a new session with the given ID and options.

Deletes a globally stored program.

Deletes a session by ID.

Retrieves a globally stored program.

Gets a program from a session.

Gets a session by ID, automatically updating the last_accessed timestamp.

Gets statistics about the session store.

Lists all active session IDs.

Checks if a session exists.

Starts the SessionStore GenServer.

Stores a program globally, accessible to any worker.

Stores worker-session affinity mapping.

Updates a session using the provided update function.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

cleanup_expired_sessions()

@spec cleanup_expired_sessions() :: non_neg_integer()

Manually triggers cleanup of expired sessions.

Returns

The number of sessions that were cleaned up.

cleanup_expired_sessions(server)

@spec cleanup_expired_sessions(GenServer.server()) :: non_neg_integer()

create_session(session_id, opts \\ [])

@spec create_session(
  String.t(),
  keyword()
) :: {:ok, Snakepit.Bridge.Session.t()} | {:error, term()}

Creates a new session with the given ID and options.

Parameters

  • session_id - Unique session identifier
  • opts - Keyword list of options passed to Session.new/2

Returns

{:ok, session} if successful, {:error, reason} if failed.

Examples

{:ok, session} = SessionStore.create_session("session_123")
{:ok, session} = SessionStore.create_session("session_456", ttl: 7200)

create_session(server, session_id, opts)

@spec create_session(GenServer.server(), String.t(), keyword()) ::
  {:ok, Snakepit.Bridge.Session.t()} | {:error, term()}

delete_global_program(program_id)

@spec delete_global_program(String.t()) :: :ok

Deletes a globally stored program.

Parameters

  • program_id - The program identifier

Returns

:ok always (idempotent operation).

delete_global_program(server, program_id)

@spec delete_global_program(GenServer.server(), String.t()) :: :ok

delete_session(session_id)

@spec delete_session(String.t()) :: :ok

Deletes a session by ID.

Parameters

  • session_id - The session identifier

Returns

:ok always (idempotent operation).

delete_session(server, session_id)

@spec delete_session(GenServer.server(), String.t()) :: :ok

get_global_program(program_id)

@spec get_global_program(String.t()) :: {:ok, map()} | {:error, :not_found}

Retrieves a globally stored program.

Parameters

  • program_id - The program identifier

Returns

{:ok, program_data} if found, {:error, :not_found} if not found.

get_global_program(server, program_id)

@spec get_global_program(GenServer.server(), String.t()) ::
  {:ok, map()} | {:error, :not_found}

get_program(session_id, program_id)

@spec get_program(String.t(), String.t()) :: {:ok, map()} | {:error, :not_found}

Gets a program from a session.

get_session(session_id)

@spec get_session(String.t()) ::
  {:ok, Snakepit.Bridge.Session.t()} | {:error, :not_found}

Gets a session by ID, automatically updating the last_accessed timestamp.

Parameters

  • session_id - The session identifier

Returns

{:ok, session} if found, {:error, :not_found} if not found.

get_session(server, session_id)

@spec get_session(GenServer.server(), String.t()) ::
  {:ok, Snakepit.Bridge.Session.t()} | {:error, :not_found}

get_stats()

@spec get_stats() :: map()

Gets statistics about the session store.

Returns

A map containing various statistics about the session store.

get_stats(server)

@spec get_stats(GenServer.server()) :: map()

list_sessions()

@spec list_sessions() :: [String.t()]

Lists all active session IDs.

Returns

A list of all active session IDs.

list_sessions(server)

@spec list_sessions(GenServer.server()) :: [String.t()]

session_exists?(session_id)

@spec session_exists?(String.t()) :: boolean()

Checks if a session exists.

Parameters

  • session_id - The session identifier

Returns

true if the session exists, false otherwise.

session_exists?(server, session_id)

@spec session_exists?(GenServer.server(), String.t()) :: boolean()

start_link(opts \\ [])

@spec start_link(keyword()) :: GenServer.on_start()

Starts the SessionStore GenServer.

Options

  • :name - The name to register the GenServer (default: MODULE)
  • :table_name - The ETS table name (default: :snakepit_sessions)
  • :cleanup_interval - Cleanup interval in milliseconds (default: 60_000)
  • :default_ttl - Default TTL for sessions in seconds (default: 3600)

store_global_program(program_id, program_data)

@spec store_global_program(String.t(), map()) :: :ok | {:error, term()}

Stores a program globally, accessible to any worker.

This is used for anonymous operations where programs need to be accessible across different pool workers.

Parameters

  • program_id - Unique program identifier
  • program_data - Program data to store

Returns

:ok if successful, {:error, reason} if failed.

store_global_program(server, program_id, program_data)

@spec store_global_program(GenServer.server(), String.t(), map()) ::
  :ok | {:error, term()}

store_program(session_id, program_id, program_data)

@spec store_program(String.t(), String.t(), map()) :: :ok | {:error, term()}

Stores a program in a session.

store_worker_session(session_id, worker_id)

@spec store_worker_session(String.t(), String.t()) :: :ok

Stores worker-session affinity mapping.

update_program(session_id, program_id, program_data)

@spec update_program(String.t(), String.t(), map()) :: :ok | {:error, term()}

Updates a program in a session.

update_session(session_id, update_fn)

@spec update_session(String.t(), (Snakepit.Bridge.Session.t() ->
                              Snakepit.Bridge.Session.t())) ::
  {:ok, Snakepit.Bridge.Session.t()} | {:error, term()}

Updates a session using the provided update function.

The update function receives the current session and should return the updated session. The operation is atomic.

Parameters

  • session_id - The session identifier
  • update_fn - Function that takes a session and returns an updated session

Returns

{:ok, updated_session} if successful, {:error, reason} if failed.

Examples

{:ok, session} = SessionStore.update_session("session_123", fn session ->
  Session.put_program(session, "prog_1", %{data: "example"})
end)

update_session(server, session_id, update_fn)

@spec update_session(GenServer.server(), String.t(), (Snakepit.Bridge.Session.t() ->
                                                  Snakepit.Bridge.Session.t())) ::
  {:ok, Snakepit.Bridge.Session.t()} | {:error, term()}