reki

Types

A registry that manages actors by key. Similar to Discord’s gen_registry, this allows you to look up or start actors on demand, ensuring only one actor exists per key.

Architecture

Reki uses an ETS table for fast O(1) lookups, with a registry actor that handles process lifecycle (starting new actors, cleaning up dead ones). When a managed actor dies, reki receives an EXIT signal and removes the stale entry from ETS.

The ETS table is owned by the registry actor. If the actor crashes, the BEAM automatically destroys the table. When the supervisor restarts the actor, a fresh table is created — no stale entries from a previous life.

Stale entries

There’s a brief window between when a process dies and when reki processes the EXIT signal. During this window, lookup or lookup_or_start may return a stale Subject pointing to a dead process. This is the tradeoff for fast O(1) lookups.

pub opaque type Registry(key, msg)
pub opaque type RegistryMessage(key, msg)

Values

pub fn lookup(
  registry: Registry(key, msg),
  key: key,
) -> option.Option(process.Subject(msg))

Looks up an actor by key in the registry, without starting one if missing.

Returns None if no actor exists for the given key. This is a direct ETS read, so it’s fast but may return a stale Subject if a process just died.

Use lookup_or_start if you want to start an actor when the key is missing.

pub fn lookup_or_start(
  registry: Registry(key, msg),
  key: key,
  start_fn: fn(key) -> Result(
    actor.Started(process.Subject(msg)),
    actor.StartError,
  ),
) -> Result(process.Subject(msg), actor.StartError)

Looks up an actor by key, or starts one if it doesn’t exist.

This is the primary function for getting an actor from the registry. It first checks ETS for an existing entry (fast O(1) lookup), and only goes through the registry actor if the key isn’t found.

In rare cases, this may return a stale Subject if a process just died but reki hasn’t processed the EXIT yet. If calling the returned Subject fails, retry with lookup_or_start_slow.

pub fn new() -> Registry(key, msg)

Create a registry. Call this at the start of your program before creating the supervision tree.

Important: Each call creates a unique atom for the ETS table name. Atoms are never garbage collected by the BEAM, so this function must only be called a fixed number of times (e.g. once per registry at app startup). Do not call new() dynamically in a loop or on each request.

pub fn start(
  registry: Registry(key, msg),
) -> Result(actor.Started(Registry(key, msg)), actor.StartError)

Start the registry. You likely want to use the supervised function instead, to add the registry to your supervision tree, but this may be useful in tests.

pub fn supervised(
  registry: Registry(key, msg),
) -> supervision.ChildSpecification(Registry(key, msg))

A specification for starting the registry under a supervisor.

Search Document