Skip to content

Instantly share code, notes, and snippets.

@ndac-todoroki
Created July 15, 2018 06:22
Show Gist options
  • Save ndac-todoroki/00c71ff37c8f20e7d7213c6936309c19 to your computer and use it in GitHub Desktop.
Save ndac-todoroki/00c71ff37c8f20e7d7213c6936309c19 to your computer and use it in GitHub Desktop.
[Elixir] add/remove children by unique name under DynamicSupervisor
defmodule DSV do
use DynamicSupervisor
@registry Registry.ViaTest
def start_link(args), do: DynamicSupervisor.start_link(__MODULE__, args, name: __MODULE__)
def init(_), do: DynamicSupervisor.init(strategy: :one_for_one)
def add_child(name) when name |> is_binary do
pid = child_process(name)
spec = GS.child_spec(name: pid)
DynamicSupervisor.start_child(__MODULE__, spec)
end
def remove_child(name) when name |> is_binary do
[{pid, _}] = Registry.lookup(@registry, name)
:ok = DynamicSupervisor.terminate_child(__MODULE__, pid)
Registry.unregister(Registry.ViaTest, name)
end
def child_process(name), do: {:via, Registry, {@registry, name}}
end
defmodule GS do
use GenServer
def start_link(args) do
opts = args |> Keyword.take([:name])
GenServer.start_link(__MODULE__, args, opts)
end
def init(args), do: {:ok, args}
def handle_call(:hello, _from, state), do: {:reply, "hello", state}
def handle_cast(:crash, state), do: raise "Crashed"
end
# Setup
Registry.start_link(keys: :unique, name: Registry.ViaTest)
DSV.start_link([])
# Create child with unique name
name = "todoroki"
DSV.add_child(name)
# communicate!
name |> DSV.child_process |> GenServer.call(:hello)
# crashes and restarts!
name |> DSV.child_process |> GenServer.cast(:term)
# communicate again!
name |> DSV.child_process |> GenServer.call(:hello)
# remove the child
DSV.remove_child(name)
# now you can not talk
name |> DSV.child_process |> GenServer.call(:hello)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment