Normandy.Behaviours.SessionStore.Mnesia (normandy v2.2.0)

View Source

Distributed, durable SessionStore over OTP-native Mnesia ("distributed ETS"). ram_copies tables are replicated ETS; :mnesia.transaction/1 serializes per-session appends (the FOR-UPDATE equivalent), so concurrent/cross-node appends never lose an entry. Mnesia stores Erlang terms natively, so content / turn_state / config_template need no term_to_binary.

The handle is %{entries: table, sessions: table}. The host (or Normandy.Cluster) calls create_tables/1 with copies: :disc_copies for durable, full-cluster-restart survival (the production default); ram_copies (test/default new/0) is faster but only meaningful with ≥2 nodes. Configure via {Normandy.Behaviours.SessionStore.Mnesia, entries: :..., sessions: :...}.

Normandy does not start Mnesia with the application; this store starts it on first use. A release that uses this store must include Mnesia: add :mnesia to your application's extra_applications.

Summary

Functions

Creates the two Mnesia tables. A writable Mnesia dir is set with -mnesia dir or the :mnesia app env.

Deletes the session's row and every entry of its tree that no other session reaches: its chain and any branch it left with an explicit parent_id (Normandy.Behaviours.SessionStore.delete_session/2).

Test/default handle: fresh uniquely-named ram_copies tables on this node.

Functions

create_tables(opts)

@spec create_tables(keyword()) :: :ok

Creates the two Mnesia tables. A writable Mnesia dir is set with -mnesia dir or the :mnesia app env.

Options

  • :entries (atom/0) - Required. The entries table.

  • :sessions (atom/0) - Required. The sessions table.

  • :copies - :disc_copies converts this node's schema to disc first so the tables survive a restart (needs a writable Mnesia dir). The default value is :disc_copies.

  • :nodes (list of atom/0) - The nodes holding copies (default: [node()]).

  • :wait_timeout (timeout/0) - How long to wait for the tables to load, in ms; raises on timeout. The default value is 30000.

delete_session(map, session_id)

Deletes the session's row and every entry of its tree that no other session reaches: its chain and any branch it left with an explicit parent_id (Normandy.Behaviours.SessionStore.delete_session/2).

Forks share ancestor entries here, and an entry's parent link sits inside its data, so finding the entries another session still uses scans both tables: O(entries + sessions) under a write lock on both, which blocks every other write to the store meanwhile.

new(opts \\ [])

@spec new(keyword()) :: %{entries: atom(), sessions: atom()}

Test/default handle: fresh uniquely-named ram_copies tables on this node.

Options

  • :entries (atom/0) - The entries table (default: a unique name).

  • :sessions (atom/0) - The sessions table (default: a unique name).