Raxol.Core.Stores.Dets (Raxol Core v2.6.0)

Copy Markdown View Source

Shared DETS lifecycle for ETS-backed stores with optional disk persistence.

An ETS-backed store keeps its working set in one or more :named_table ETS tables and, when configured, mirrors the canonical records to a DETS file so they survive a process restart. This module covers:

  • resolving the DETS path from start options or application config,
  • opening (or creating) the file and replaying its records back into the caller's live ETS tables on boot,
  • writing through to disk on each mutation,
  • flushing and closing the file on shutdown.

The caller owns its ETS table topology and replay logic. The replay step is supplied as a function so a store with secondary indices can re-index every record as it is read back. A nil handle is a valid no-op throughout, so a store with persistence disabled can call these helpers unconditionally.

Pure: depends only on :dets, File, and Path.

Summary

Types

An open DETS handle, or nil when persistence is disabled.

Functions

Wipe every persisted record. No-op when persistence is disabled.

Flush and close the DETS file. No-op when persistence is disabled.

Delete a record from disk. No-op when persistence is disabled.

Open (or create) the DETS file at path under table name dets_name, replay every stored record through replay_fun, and return the handle.

Write a record through to disk. No-op when persistence is disabled.

Resolve the configured DETS path, or nil when persistence is disabled.

Types

handle()

@type handle() :: :dets.tab_name() | nil

An open DETS handle, or nil when persistence is disabled.

Functions

clear(dets)

@spec clear(handle()) :: :ok

Wipe every persisted record. No-op when persistence is disabled.

close(dets)

@spec close(handle()) :: :ok

Flush and close the DETS file. No-op when persistence is disabled.

Intended for a store's terminate/2. A SIGKILL can still lose the most recent write window; use a real database for stronger guarantees.

delete(dets, key)

@spec delete(handle(), term()) :: :ok

Delete a record from disk. No-op when persistence is disabled.

open!(dets_name, path, replay_fun)

@spec open!(atom(), binary(), ({term(), term()} -> any())) :: handle()

Open (or create) the DETS file at path under table name dets_name, replay every stored record through replay_fun, and return the handle.

replay_fun is called once per {key, value} record for its side effect (re-inserting into the caller's ETS tables); its return value is ignored.

Raises when the parent directory cannot be created or the file cannot be opened, so a misconfigured path surfaces at boot rather than degrading silently to an in-memory store.

put(dets, key, value)

@spec put(handle(), term(), term()) :: :ok

Write a record through to disk. No-op when persistence is disabled.

resolve_path(opts, otp_app, config_key)

@spec resolve_path(keyword(), atom(), atom()) :: binary() | nil

Resolve the configured DETS path, or nil when persistence is disabled.

An explicit :dets_path in opts always wins; otherwise the value falls back to Application.get_env(otp_app, config_key). Returns nil when neither is set, signalling in-memory-only operation.