ExWapp.Store.Ets (ExWapp v0.1.2)

Copy Markdown View Source

ETS-backed store with file persistence.

This is the default store adapter. It keeps data in an ETS table for fast access and persists to a file on disk using the versioned ExWapp store codec. Legacy ETF-backed files are migrated on first load.

Options

  • :path - File path for persistence. Defaults to ~/.cache/ex_wapp/session.etf

Examples

# Use with default path
store = ExWapp.Store.Ets.new()

# Use with custom path
store = ExWapp.Store.Ets.new(path: "/var/lib/myapp/wa_session.etf")

# Store and retrieve data
:ok = ExWapp.Store.persist(store, %{user: "Alice"})
{:ok, %{user: "Alice"}} = ExWapp.Store.load(store)

Implementation Notes

  • A linked writer process owns the ETS tables and serializes mutations
  • Top-level domains, Signal sessions, device cache, and messages are stored separately so an update does not copy or replace unrelated state
  • Caller-owned batches coalesce sync mutations into one durable snapshot
  • Message streams traverse the ordered message table lazily by JID and cursor
  • Snapshot encoding runs in a short-lived process to release its large heap immediately after compression and I/O
  • File is loaded on new/1 if it exists

Summary

Types

t()

@type t() :: %ExWapp.Store.Ets{
  device_cache_table: :ets.tid(),
  message_table: ExWapp.Store.MessageTable.t(),
  path: Path.t(),
  signal_table: :ets.tid(),
  table: :ets.tid(),
  writer: pid() | nil
}

Functions

get(store, key, default \\ nil)

@spec get(t(), atom(), term()) :: term()

load_device_cache(ets)

@spec load_device_cache(t()) :: map()

load_path(path)

@spec load_path(Path.t()) :: {:ok, ExWapp.Store.data()} | {:error, term()}

Loads store data directly from a persisted file path.

This is useful for one-off reads, such as pairing handoff flows, where creating a full ETS-backed store instance would hide missing-file errors by defaulting to an empty map.

load_signal_sessions(ets)

@spec load_signal_sessions(t()) :: ExWapp.Signal.SessionStore.t()

persist_device_cache(store, cache)

@spec persist_device_cache(t(), map()) :: :ok | {:error, term()}

persist_signal_sessions(store, sessions)

@spec persist_signal_sessions(t(), term()) :: :ok | {:error, term()}