Skip to content

Instantly share code, notes, and snippets.

@cr0t
Created September 6, 2024 13:26
Show Gist options
  • Save cr0t/14ee94a1b4c42cfebea1b1e8112f3579 to your computer and use it in GitHub Desktop.
Save cr0t/14ee94a1b4c42cfebea1b1e8112f3579 to your computer and use it in GitHub Desktop.
Two (very simple) process registries written in Elixir, one with is fully based on GenServer, while the other stores its state in an ETS table
defmodule RegistryEts do
use GenServer
def register(key, pid \\ self()),
do: GenServer.call(__MODULE__, {:register, key, pid})
def whereis(key) do
case :ets.lookup(__MODULE__, key) do
[{^key, pid}] -> pid
_ -> nil
end
end
def start_link(),
do: GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
@impl GenServer
def init(:ok) do
:ets.new(__MODULE__, [:named_table, :protected, :set])
{:ok, nil}
end
@impl GenServer
def handle_call({:register, key, pid}, _from, state) do
if is_nil(whereis(key)) do
Process.monitor(pid)
:ets.insert(__MODULE__, {key, pid})
{:reply, :ok, state}
else
{:reply, :error, state}
end
end
@impl GenServer
def handle_info({:DOWN, _ref, :process, pid, _reason}, state) do
:ets.match_delete(__MODULE__, {:_, pid})
{:noreply, state}
end
end
defmodule RegistryGen do
use GenServer
def register(key),
do: GenServer.call(__MODULE__, {:register, key, self()})
def whereis(key),
do: GenServer.call(__MODULE__, {:whereis, key})
def start_link(),
do: GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
@impl GenServer
def init(:ok) do
Process.flag(:trap_exit, true)
{:ok, %{}}
end
@impl GenServer
def handle_call({:register, key, pid}, _from, processes) do
if Map.has_key?(processes, key) do
{:reply, :error, processes}
else
Process.link(pid)
{:reply, :ok, Map.put_new(processes, key, pid)}
end
end
@impl GenServer
def handle_call({:whereis, key}, _from, processes),
do: {:reply, Map.get(processes, key), processes}
@impl GenServer
def handle_info({:EXIT, pid, _reason}, processes),
do: {:noreply, processes |> Enum.reject(fn {_, v} -> v == pid end) |> Map.new()}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment