Hyper.Cluster.Routing (Hyper v0.1.0)

Copy Markdown View Source

Cluster-wide VM routing registry: maps {vm_id, component} -> pid so any node can name a VM's processes (via/1) and find which machine runs a VM (whereis/1). A Horde.Registry (DeltaCRDT) with members: :auto, so it forms over the BEAM cluster libcluster builds.

Kept as its own CRDT, separate from Hyper.Cluster.Budget, so high-frequency budget telemetry never shares this routing table's delta stream or failure domain.

Summary

Functions

Every VM the cluster currently knows about, paired with the node it runs on.

The vm_id whose :supervisor process is pid, or nil. Consults the local replica via a registry match spec; intended to be called on the node that owns pid (see Hyper.id/1).

The registry name.

Register the calling process under key from inside its own init.

The pid of vm_id's VM supervisor process, or nil if unknown.

A :via tuple for registering/naming a process under key.

Which node currently runs vm_id? nil if unknown.

Functions

all()

@spec all() :: [{Hyper.Vm.Id.t(), node()}]

Every VM the cluster currently knows about, paired with the node it runs on.

id_for(pid)

@spec id_for(pid()) :: Hyper.Vm.Id.t() | nil

The vm_id whose :supervisor process is pid, or nil. Consults the local replica via a registry match spec; intended to be called on the node that owns pid (see Hyper.id/1).

name()

@spec name() :: atom()

The registry name.

register_self(key)

@spec register_self(term()) :: :ok | {:error, {:already_registered, pid()}}

Register the calling process under key from inside its own init.

Prefer this over starting a process with a {:via, Horde.Registry, _} name. OTP's post-start name check (gen:get_proc_name) calls whereis_name immediately after the synchronous register, but Horde materialises the name into its local ETS only asynchronously, via the DeltaCRDT diff loop. Under registry churn that read loses the race and OTP aborts startup with {:process_not_registered_via, Horde.Registry}. Registering from within init carries no such self-check, while leaving the name cluster-resolvable through via/1 once the diff propagates (callers already tolerate that lag).

supervisor_of(vm_id)

@spec supervisor_of(Hyper.Vm.Id.t()) :: pid() | nil

The pid of vm_id's VM supervisor process, or nil if unknown.

via(key)

@spec via(term()) :: {:via, module(), {atom(), term()}}

A :via tuple for registering/naming a process under key.

whereis(vm_id)

@spec whereis(Hyper.Vm.Id.t()) :: node() | nil

Which node currently runs vm_id? nil if unknown.