Last active
September 25, 2022 19:57
-
-
Save IanVaughan/1b3f14b430bb8480e07e2d8c9d48d94d to your computer and use it in GitHub Desktop.
elixir genserver timeouts
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 CallsProcessOnTimeout do | |
use GenServer | |
def start_link(opts) do | |
self() |> IO.inspect(label: "#{__MODULE__}.start_link") | |
GenServer.start_link(__MODULE__, opts, name: __MODULE__) | |
end | |
def init(opts) do | |
self() |> IO.inspect(label: "#{__MODULE__}.init returing :ok, pid") | |
{:ok, opts, 1000} | |
end | |
def handle_info(:timeout, %{timeout_for: timeout_for, call_timeout: call_timeout} = state) do | |
self() |> IO.inspect(label: "#{__MODULE__}.handle_info :timeout") | |
ProcessThatTimesout.long_call(%{call_timeout: call_timeout}) | |
{:noreply, state, timeout_for} | |
end | |
end | |
defmodule ProcessThatTimesout do | |
use GenServer | |
def start_link(opts) do | |
self() |> IO.inspect(label: "#{__MODULE__}.start_link") | |
GenServer.start_link(__MODULE__, opts, name: __MODULE__) | |
end | |
def init(opts) do | |
self() |> IO.inspect(label: "#{__MODULE__}.init returing :ok, pid") | |
{:ok, opts} | |
end | |
def long_call(%{call_timeout: call_timeout}) do | |
self() |> IO.inspect(label: "#{__MODULE__}.long_call timeout:#{inspect call_timeout}") | |
GenServer.call(__MODULE__, :long_call, call_timeout) | |
end | |
def handle_call(:long_call, _from, %{sleep_for: sleep_for} = state) do | |
self() |> IO.inspect(label: "#{__MODULE__}.handle_info :long_call") | |
:timer.sleep(sleep_for) | |
{:reply, :done, state} | |
end | |
end | |
defmodule Runner do | |
@doc """ | |
iex(1)> self() | |
#PID<0.114.0> | |
iex(2)> Runner.run1 | |
Elixir.ProcessThatTimesout.start_link: #PID<0.114.0> | |
Elixir.ProcessThatTimesout.init returing :ok, pid: #PID<0.118.0> | |
Elixir.ProcessThatTimesout.long_call timeout:2000: #PID<0.114.0> | |
Elixir.ProcessThatTimesout.handle_info :long_call: #PID<0.118.0> | |
:done | |
iex(3)> self() | |
#PID<0.114.0> | |
""" | |
def run1 do | |
ProcessThatTimesout.start_link(%{sleep_for: 1000}) | |
ProcessThatTimesout.long_call(%{call_timeout: 2000}) | |
end | |
@doc """ | |
iex(1)> self() | |
#PID<0.106.0> | |
iex(2)> Runner.run2 | |
Elixir.ProcessThatTimesout.start_link: #PID<0.106.0> | |
Elixir.ProcessThatTimesout.init returing :ok, pid: #PID<0.111.0> | |
Elixir.ProcessThatTimesout.long_call timeout:1000: #PID<0.106.0> | |
Elixir.ProcessThatTimesout.handle_info :long_call: #PID<0.111.0> | |
** (exit) exited in: GenServer.call(ProcessThatTimesout, :long_call, 1000) | |
** (EXIT) time out | |
(elixir) lib/gen_server.ex:774: GenServer.call/3 | |
iex(1)> self() | |
#PID<0.106.0> | |
""" | |
def run2 do | |
ProcessThatTimesout.start_link(%{sleep_for: 2000}) | |
ProcessThatTimesout.long_call(%{call_timeout: 1000}) | |
end | |
@doc """ | |
iex(1)> Runner.run3 | |
Elixir.ProcessThatTimesout.start_link: #PID<0.108.0> | |
Elixir.ProcessThatTimesout.init returing :ok, pid: #PID<0.110.0> | |
Elixir.CallsProcessOnTimeout.start_link: #PID<0.108.0> | |
Elixir.CallsProcessOnTimeout.init returing :ok, pid: #PID<0.111.0> | |
{:ok, #PID<0.111.0>} | |
Elixir.CallsProcessOnTimeout.handle_info :timeout: #PID<0.111.0> | |
Elixir.ProcessThatTimesout.long_call timeout:1000: #PID<0.111.0> | |
Elixir.ProcessThatTimesout.handle_info :long_call: #PID<0.110.0> | |
** (EXIT from #PID<0.108.0>) evaluator process exited with reason: exited in: GenServer.call(ProcessThatTimesout, :long_call, 1000) | |
** (EXIT) time out | |
Interactive Elixir (1.5.2) - press Ctrl+C to exit (type h() ENTER for help) | |
iex(1)> | |
19:25:48.060 [error] GenServer CallsProcessOnTimeout terminating | |
** (stop) exited in: GenServer.call(ProcessThatTimesout, :long_call, 1000) | |
** (EXIT) time out | |
(elixir) lib/gen_server.ex:774: GenServer.call/3 | |
play2.exs:17: CallsProcessOnTimeout.handle_info/2 | |
(stdlib) gen_server.erl:601: :gen_server.try_dispatch/4 | |
(stdlib) gen_server.erl:667: :gen_server.handle_msg/5 | |
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3 | |
Last message: :timeout | |
State: %{call_timeout: 1000, timeout_for: 1000} | |
nil | |
iex(2)> self() | |
#PID<0.113.0> | |
""" | |
def run3 do | |
ProcessThatTimesout.start_link(%{sleep_for: 2000}) | |
CallsProcessOnTimeout.start_link(%{timeout_for: 1000, call_timeout: 1000}) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment