When I use IEx.pry or a breakpoint (via :int.break()), the interactive shell dies too quickly, and I only have ~10 seconds before I lose my session:
** (EXIT from #PID<0.606.0>) shell process exited with reason: shutdown
And 10 seconds isn’t enough to productively debug my code in the shell/debugger. My best guess is that there’s a default timeout in a :supervisor.child_spec that I need to override, but I’m not 100% sure.
This is what I’ve tried so far (and why they haven’t worked so far):
- Increase the :shutdown parameter to :infinity in the child_specs to Supervisor.start_link() in MyApp.Application.
- Updated the cowboy timeouts (idle_timeout, linger_timeout, request_timeout, shutdown_timeout) because Observer indicated that my request is a cowboy process. I don’t think it’s likely that it’s cowboy, though. If the default is 60s, I’m not even getting close to 60s.
- Instead of using IEx.pry, I tried using the debugger (via
:ni.break) - Just noting that I can’t use
mix test --trace, which sets the timeout to :infinity. Since I’m trying to debug a non-test Endpoint action, this flag won't help.
How do people use the debugger/IEx.pry? (I'm coming from a Ruby/JS world, so I like to have some time to inspect the variables.) Are people just not encountering the 10s timeout like I am? Or is there some common configuration that I’m missing for my troubleshooting needs?
My Supervisor/child configs in application.ex:
Note the shutdown: :infinity configuration.
defmodule MyApp.Application do
use Application
def start(_type, _args) do
children = [
MyApp.Repo,
{MyApp.Web.Endpoint, [shutdown: :infinity]},
{Phoenix.PubSub, [name: MyApp.PubSub, adapter: Phoenix.PubSub.PG2]},
{MyApp.Middleware.Ets.AnEtsThing, [name: MyApp.Middleware.Ets.AnEtsThing, table_name: :my_app_config_2]},
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
def config_change(changed, _new, removed) do
MyApp.Web.Endpoint.config_change(changed, removed)
:ok
end
end
My cowboy configs in dev.exs
config :my_app, MyApp.Web.Endpoint,
http: [
port: 4000,
protocol_options: [
request_timeout: 100_000_000,
shutdown_timeout: 100_000_000,
idle_timeout: 100_000_000,
linger_timeout: 100_000_000,
]
]
Console inspection of Cowboy configs
This is just to confirm that I was configuring Cowboy in the right place. I confirmed that toggling the port did affect the ports.
iex(4)> MyApp.Web.Endpoint.config(:http)
[
port: 4001,
protocol_options: [
request_timeout: 100000000,
shutdown_timeout: 100000000,
idle_timeout: 100000000,
linger_timeout: 100000000
]
]
This is what I see in the IEX console by running iex -S mix phx.server:
Note that there is no stacktrace that tells me what is killing my pry session.
Interactive Elixir (1.10.3) - press Ctrl+C to exit (type h() ENTER for help)
Request to pry #PID<0.718.0> at MyApp.Foo.foo/3 (lib/my_app/foo.ex:16)
14:
15: def foo(_parent, _args, %{context: %{bar: bar}}) do
16: require IEx; IEx.pry
17:
18: some_code()
Allow? [Yn] <=== I type "Enter"
Interactive Elixir (1.10.3) - press Ctrl+C to exit (type h() ENTER for help)
pry(1)> DateTime.utc_now <=== I type this to show when the pry session starts
~U[2020-12-28 06:18:27.861251Z]
** (EXIT from #PID<0.718.0>) shell process exited with reason: shutdown
...
Interactive Elixir (1.10.3) - press Ctrl+C to exit (type h() ENTER for help)
pry(1)> DateTime.utc_now
~U[2020-12-28 06:18:40.420951Z] <== ~13 seconds, pry session dies
shutdown(likely the cause of the absence of a stacktrace), it emits the same signal, thus the shell exits withshutdown. The process may receive theshutdownsignal from multiple sources, you can check the origin trapping signals in the process and following the chain. - José M