Skip to content

Instantly share code, notes, and snippets.

@IanVaughan
Last active August 10, 2018 11:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IanVaughan/8e6dc56d8f49c1a52cc8dab98eabbcbb to your computer and use it in GitHub Desktop.
Save IanVaughan/8e6dc56d8f49c1a52cc8dab98eabbcbb to your computer and use it in GitHub Desktop.
elixir genserver process stop from init within start_child supervisor restart
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>
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