Mix.install([
{:erlfdb, "~> 1.0"},
{:dgen, github: "foundationdb-beam/dgen"}
])Intro
DGen.Registry is a distributed Elixir process registry that is built to gracefully and automatically handle nodes joining and leaving your cluster.
If you're already running DGen, all you have to do to use the registry is
- Ensure your nodes are capable of communication (e.g. VM config, network, cookie)
- Add a new child to your supervision tree
As long as you do this, DGen.Registry will take care of clustering the Elixir VMs with each other and will ensure that the dataset they share (namely process registrations) is consistent across the cluster.
Nodes can join and leave at your will. DGen.Registry keeps everything up-to-date.
Reminder: The
DGenproject is a set of OTP-like utilities that inherit their distributed consensus from a backend database. As of the time of writing, the single supported backend is FoundationDB. Thus,DGen.Registryrequires that your application connects to a running FoundationDB cluster.
What this document covers
This document, an interactive Livebook, covers the "Getting Started" of DGen.Registry, including how to register processes and metadata and how to query them.
For a discussion of the consistency guarantees of DGen.Registry, please see the :dgen_registry Design Doc
Getting Started
tenant = :dgen_erlfdb.sandbox_open("lb", "acme_corp")DGen.Registry.start_link(:my_registry, tenant)defmodule Player do
use GenServer
def start_link(name) do
GenServer.start_link(__MODULE__, %{}, name: {:via, DGen.Registry, {:my_registry, name}})
end
def move_to_room(name, room) do
:dgen_registry.set_metadata(
{:my_registry, name},
%{index: %{room: room}, data: %{}}
)
end
@impl true
def init(_) do
{:ok, %{}}
end
end
defmodule Room do
def list_players(room) do
:dgen_registry.query(:my_registry, %{room: room})
|> Enum.map(fn %{name: name, pid: pid} -> {name, pid} end)
end
endPlayer.start_link("alice")GenServer.whereis({:via, DGen.Registry, {:my_registry, "alice"}})Player.move_to_room("alice", 37)Room.list_players(37)Player.start_link("bob")Player.move_to_room("bob", 37)Room.list_players(37)GenServer.stop({:via, DGen.Registry, {:my_registry, "bob"}})Room.list_players(37)