Created
September 22, 2017 15:20
-
-
Save schmalz/deba894444a7260cbd366c78a8c9d5b2 to your computer and use it in GitHub Desktop.
Designing for Scalability with Erlang/OTP - Ch 8 - Coffee Supervisor - Elixir
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Sup do | |
def start(name, child_spec_list) do | |
Process.register(pid = spawn(__MODULE__, :init, [child_spec_list]), name) | |
{:ok, pid} | |
end | |
def stop(name), do: send(name, :stop) | |
def init(child_spec_list) do | |
Process.flag(:trap_exit, :true) | |
child_spec_list | |
|> start_children() | |
|> loop() | |
end | |
defp start_children(child_spec_list) do | |
for {m, f, a} <- child_spec_list, do: {elem(apply(m, f, a), 1), {m, f, a}} | |
end | |
defp loop(child_list) do | |
receive do | |
{:EXIT, pid, :normal} -> loop(List.keydelete(child_list, pid, 0)) | |
{:EXIT, pid, _reason} -> loop(restart_child(pid, child_list)) | |
:stop -> terminate(child_list) | |
end | |
end | |
defp restart_child(pid, child_list) do | |
{^pid, {m, f, a}} = List.keyfind(child_list, pid, 0) | |
{:ok, new_pid} = apply(m, f, a) | |
List.keyreplace(child_list, pid, 0, {new_pid, {m, f, a}}) | |
end | |
defp terminate(child_list), do: Enum.each(child_list, fn({pid, _}) -> Process.exit(pid, :kill) end) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment