Registry, DynamicSupervisor & PartitionSupervisor
Duplicate-key registries act as local pub/sub:
34.1 DynamicSupervisor — start children on demand
children = [{DynamicSupervisor, name: MyApp.RoomSup, strategy: :one_for_one}]
{:ok, pid} = DynamicSupervisor.start_child(MyApp.RoomSup, {ChatRoom, "lobby"})
DynamicSupervisor.terminate_child(MyApp.RoomSup, pid)
DynamicSupervisor.which_children(MyApp.RoomSup)34.2 Registry — local process registry (key → pid)
Duplicate-key registries act as local pub/sub:
{Registry, keys: :unique, name: MyApp.Registry}
defmodule ChatRoom do
use GenServer
def start_link(name), do: GenServer.start_link(__MODULE__, name, name: via(name))
def via(name), do: {:via, Registry, {MyApp.Registry, name}}
def say(room, msg), do: GenServer.cast(via(room), {:say, msg})
@impl true
def init(name), do: {:ok, %{name: name, messages: []}}
@impl true
def handle_cast({:say, m}, s), do: {:noreply, %{s | messages: [m | s.messages]}}
end
Registry.lookup(MyApp.Registry, "lobby") # [{pid, value}]{Registry, keys: :duplicate, name: MyApp.PubSub}
Registry.register(MyApp.PubSub, "topic", [])
Registry.dispatch(MyApp.PubSub, "topic", fn entries -> for {pid, _} <- entries, do: send(pid, :event) end)34.3 PartitionSupervisor — scale a bottleneck
Starts N copies (default = schedulers) and routes by key.
{PartitionSupervisor, child_spec: DynamicSupervisor, name: MyApp.DynSups}
DynamicSupervisor.start_child({:via, PartitionSupervisor, {MyApp.DynSups, self()}}, spec)