Malachi.Cluster.ReplicatedMetadata (malachi v0.8.13)

View Source

The control plane's metadata made authoritative via Raft, with a local read cache.

It pairs a Malachi.Cluster.MetadataServer (one ra cluster running Malachi.Metadata.apply/2) with a local Malachi.Metadata materialized view. Mutations go through the Raft log (durable and replicated); on commit, the very same command is applied to the local cache. Because Malachi.Metadata.apply/2 is deterministic, the cache always equals the replicated state, so reads are served locally from the cache (no Raft round-trip on the hot path) with read-your-writes consistency.

The cache is correct without refreshing as long as this process is the only writer (the single-control-node topology). refresh/1 re-reads the replicated state for the multi-writer case or after recovery.

ra must already be running (e.g. :ra.start_in/1), as with Malachi.Cluster.MetadataServer.

Summary

Functions

Stateless form: submit command to the Raft cluster server_id and apply it to the caller's metadata cache, returning {metadata, reply} (the same shape as Malachi.Metadata.apply/2, so it is a drop-in metadata command function). The caller threads the cache, which lets a single operation perform several mutations with read-your-writes between them (e.g. a produce that opens and seals a segment). On a transport failure the cache is left unchanged.

Submits command through the Raft log and, on commit, applies it to the local cache too. Returns {reply, replicated_metadata}. reply is the machine reply (e.g. {:ok, root_id} or {:error, :already_exists}), or {:error, reason} on a transport failure (cache unchanged).

Stops and deletes the underlying Raft cluster (removing its on-disk state).

The local metadata view, for reads (routing, segment lookup).

Re-reads the replicated state into the cache (multi-writer or post-recovery).

Starts (or joins) the Raft cluster cluster_name and seeds the local cache from it.

Types

t()

@type t() :: %Malachi.Cluster.ReplicatedMetadata{
  cache: Malachi.Metadata.t(),
  server_id: Malachi.Cluster.MetadataServer.server_id()
}

Functions

apply_command(server_id, metadata, command)

Stateless form: submit command to the Raft cluster server_id and apply it to the caller's metadata cache, returning {metadata, reply} (the same shape as Malachi.Metadata.apply/2, so it is a drop-in metadata command function). The caller threads the cache, which lets a single operation perform several mutations with read-your-writes between them (e.g. a produce that opens and seals a segment). On a transport failure the cache is left unchanged.

command(replicated, command)

@spec command(t(), Malachi.Metadata.command()) :: {term(), t()}

Submits command through the Raft log and, on commit, applies it to the local cache too. Returns {reply, replicated_metadata}. reply is the machine reply (e.g. {:ok, root_id} or {:error, :already_exists}), or {:error, reason} on a transport failure (cache unchanged).

delete(replicated_metadata)

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

Stops and deletes the underlying Raft cluster (removing its on-disk state).

metadata(replicated_metadata)

@spec metadata(t()) :: Malachi.Metadata.t()

The local metadata view, for reads (routing, segment lookup).

refresh(replicated)

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

Re-reads the replicated state into the cache (multi-writer or post-recovery).

start(cluster_name)

@spec start(Malachi.Cluster.MetadataServer.cluster_name()) ::
  {:ok, t()} | {:error, term()}

Starts (or joins) the Raft cluster cluster_name and seeds the local cache from it.