Current section

Files

Jump to
mqttx lib mqttx session ets_store.ex
Raw

lib/mqttx/session/ets_store.ex

defmodule MqttX.Session.ETSStore do
@moduledoc """
ETS-based in-memory session store.
This is the default session store implementation. Sessions are stored in
an ETS table and persist for the lifetime of the BEAM VM.
## Options
- `:table` - Name of the ETS table (default: `:mqttx_sessions`)
## Usage
{:ok, client} = MqttX.Client.connect(
host: "localhost",
client_id: "my_client",
clean_session: false,
session_store: MqttX.Session.ETSStore
)
# Or with custom table name
{:ok, client} = MqttX.Client.connect(
host: "localhost",
client_id: "my_client",
clean_session: false,
session_store: {MqttX.Session.ETSStore, table: :my_sessions}
)
## Limitations
- Sessions are lost when the BEAM VM restarts
- Not suitable for distributed deployments (sessions are node-local)
For persistent storage across restarts, implement a custom store using
the `MqttX.Session.Store` behaviour with your preferred database.
"""
@behaviour MqttX.Session.Store
@default_table :mqttx_sessions
@impl true
def init(opts) do
table = Keyword.get(opts, :table, @default_table)
# The default :mqttx_sessions table is pre-created by MqttX.Session.ETSOwner
# under the application supervisor so it outlives transient callers. For
# custom tables (passed via opts) we fall back to creating-on-demand; the
# caller is responsible for ensuring its lifetime if longer-lived storage
# is needed.
case :ets.whereis(table) do
:undefined ->
:ets.new(table, [
:named_table,
:public,
:set,
{:read_concurrency, true},
{:write_concurrency, true}
])
_ref ->
:ok
end
{:ok, %{table: table}}
end
@impl true
def save(client_id, session, %{table: table}) do
:ets.insert(table, {client_id, session})
:ok
end
@impl true
def load(client_id, %{table: table}) do
case :ets.lookup(table, client_id) do
[{^client_id, session}] -> {:ok, session}
[] -> :not_found
end
end
@impl true
def delete(client_id, %{table: table}) do
:ets.delete(table, client_id)
:ok
end
end