Malachi.Cluster.PolicyStore (malachi v0.22.7)

View Source

The cluster's storage policy definitions: a thin facade over the ra-replicated policy cluster (Malachi.Cluster.PolicyServer), the counterpart of Malachi.Auth.AclStore. Malachi.Application starts the ra cluster at boot; this module routes definitions through the log (consensus) and reads to the local replica.

Placement reads fail open; retention reads fail closed. The two callers get opposite treatment on purpose, because the cost of being wrong is not symmetric.

get/1 answers nil when the store cannot be read, which is the same answer a topic with no policy gets, so placement falls back to the cluster-wide spread. A segment placed without its operator's rack rule is a worse placement, and healing can move it later.

fetch_all/0 hands the read error back instead, and Malachi.Cluster.RetentionCoordinator skips the whole sweep on it. Falling back there would expire under the cluster-wide limits exactly the data a more permissive policy was written to keep, on every replica, with no way back. A sweep that did not run is recovered by the next one. A deletion is not recovered at all.

There is no wire key, mix task or dashboard route reaching these yet: #194 is what opens the door. This module is where it will knock.

Summary

Functions

The policy store's ra cluster name.

Defines (or replaces) the policy named name. Returns :ok or {:error, reason}.

Removes the policy named name (idempotent). Returns :ok or {:error, reason}.

Every definition as a map from name to policy, or the read error.

The policy named name, or nil when it is undefined or the store cannot be read.

Functions

cluster_name()

@spec cluster_name() :: atom()

The policy store's ra cluster name.

define(name, policy)

@spec define(Malachi.Cluster.Policy.name(), Malachi.Cluster.Policy.t()) ::
  :ok | {:error, term()}

Defines (or replaces) the policy named name. Returns :ok or {:error, reason}.

delete(name)

@spec delete(Malachi.Cluster.Policy.name()) :: :ok | {:error, term()}

Removes the policy named name (idempotent). Returns :ok or {:error, reason}.

fetch_all()

@spec fetch_all() ::
  {:ok,
   %{required(Malachi.Cluster.Policy.name()) => Malachi.Cluster.Policy.t()}}
  | {:error, term()}

Every definition as a map from name to policy, or the read error.

Hands the failure back rather than answering with an empty map, which a caller cannot tell from a cluster that has defined no policies. Retention is that caller: see the module doc for why the two answers must not look the same there.

get(name)

The policy named name, or nil when it is undefined or the store cannot be read.