Last active
August 10, 2018 11:22
-
-
Save IanVaughan/8e6dc56d8f49c1a52cc8dab98eabbcbb to your computer and use it in GitHub Desktop.
elixir genserver process stop from init within start_child supervisor restart
This file contains 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
iex> self() | |
#PID<0.111.0> | |
iex> Runner.run | |
Elixir.MySupervisor.init, pid: #PID<0.115.0> | |
Elixir.ProcessThatCrashesInInit.init returing :ok, pid: #PID<0.116.0> | |
sup_pid: #PID<0.115.0> | |
child_pid: #PID<0.116.0> | |
Killing 1 | |
Killing 2 | |
Elixir.ProcessThatCrashesInInit.init returing :stop, pid: #PID<0.117.0> | |
Elixir.ProcessThatCrashesInInit.init returing :stop, pid: #PID<0.118.0> | |
{#PID<0.115.0>, #PID<0.116.0>} | |
** (EXIT from #PID<0.111.0>) evaluator process exited with reason: shutdown | |
iex> self() | |
#PID<0.120.0> |
This file contains 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 ProcessThatCrashesInInit do | |
use GenServer | |
def start_link do | |
GenServer.start_link(__MODULE__, 0, name: __MODULE__) | |
end | |
def init(_) do | |
case CrashOrNot.get do | |
true -> | |
self() |> IO.inspect(label: "#{__MODULE__}.init returing :stop, pid") | |
:timer.sleep(1000) | |
{:stop, "stopping"} | |
false -> | |
self() |> IO.inspect(label: "#{__MODULE__}.init returing :ok, pid") | |
{:ok, "stopping"} | |
end | |
end | |
end | |
defmodule CrashOrNot do | |
use Agent | |
def start_link, do: Agent.start_link(fn -> false end, name: __MODULE__) | |
def get, do: Agent.get(__MODULE__, fn value -> value end) | |
def set(value), do: Agent.update(__MODULE__, fn _state -> value end) | |
def flip, do: !get() |> set() | |
end | |
defmodule MySupervisor do | |
use Supervisor | |
def start_link, do: Supervisor.start_link(__MODULE__, [], name: __MODULE__) | |
def start_child(opts), do: Supervisor.start_child(__MODULE__, opts) | |
def init(_) do | |
self() |> IO.inspect(label: "#{__MODULE__}.init, pid") | |
children = [ | |
worker(ProcessThatCrashesInInit, []) | |
] | |
opts = [ | |
strategy: :simple_one_for_one, | |
max_restarts: 10, max_seconds: 1 | |
# max_restarts: 2, max_seconds: 10 | |
] | |
supervise(children, opts) | |
end | |
end | |
defmodule Runner do | |
def run do | |
{:ok, _cpid} = CrashOrNot.start_link | |
{:ok, sup_pid} = MySupervisor.start_link | |
{:ok, child_pid} = MySupervisor.start_child([]) | |
sup_pid |> IO.inspect(label: "sup_pid") | |
child_pid |> IO.inspect(label: "child_pid") | |
IO.puts "Killing 1" | |
:timer.sleep(1000) | |
Process.exit(worker_pid, :kill) | |
CrashOrNot.flip | |
IO.puts "Killing 2" | |
:timer.sleep(1000) | |
Process.exit(worker_pid, :kill) | |
{sup_pid, child_pid} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment