mon*_*ner 5 erlang timeout elixir cowboy phoenix-framework
当我使用 IEx.pry 或断点(通过:int.break())时,交互式 shell 死得太快,并且在丢失会话之前我只有大约 10 秒的时间:
** (EXIT from #PID<0.606.0>) shell process exited with reason: shutdown
10 秒\xe2\x80\x99 不足以在 shell/调试器中高效地调试我的代码。:supervisor.child_spec我最好的猜测是,我需要覆盖a 中的默认超时,但我不能 100% 确定。
这是我到目前为止尝试过的(以及为什么他们到目前为止还没有工作):
\n:ni.break)mix test --trace,它将超时设置为:无穷大。由于我\xe2\x80\x99m 尝试调试非测试端点操作,因此此标志不会有帮助。人们如何使用调试器/IEx.pry?(我来自 Ruby/JS 世界,所以我喜欢有一些时间来检查变量。)人们是否没有像我一样遇到 10 秒超时?或者我\xe2\x80\x99m 是否缺少一些常见配置来满足我的故障排除需求?
\n我的主管/孩子在 application.ex 中的配置:
\n注意shutdown: :infinity配置。
defmodule MyApp.Application do\n use Application\n\n def start(_type, _args) do\n children = [\n MyApp.Repo,\n {MyApp.Web.Endpoint, [shutdown: :infinity]},\n {Phoenix.PubSub, [name: MyApp.PubSub, adapter: Phoenix.PubSub.PG2]},\n {MyApp.Middleware.Ets.AnEtsThing, [name: MyApp.Middleware.Ets.AnEtsThing, table_name: :my_app_config_2]},\n ]\n opts = [strategy: :one_for_one, name: MyApp.Supervisor]\n Supervisor.start_link(children, opts)\n end\n\n def config_change(changed, _new, removed) do\n MyApp.Web.Endpoint.config_change(changed, removed)\n :ok\n end\nend\nRun Code Online (Sandbox Code Playgroud)\n我在 dev.exs 中的牛仔配置
\nconfig :my_app, MyApp.Web.Endpoint,\n http: [\n port: 4000,\n protocol_options: [\n request_timeout: 100_000_000,\n shutdown_timeout: 100_000_000,\n idle_timeout: 100_000_000,\n linger_timeout: 100_000_000,\n ]\n ]\nRun Code Online (Sandbox Code Playgroud)\nCowboy 配置的控制台检查
\n这只是为了确认我在正确的位置配置了 Cowboy。我确认切换端口确实会影响端口。
\niex(4)> MyApp.Web.Endpoint.config(:http)\n[\n port: 4001,\n protocol_options: [\n request_timeout: 100000000,\n shutdown_timeout: 100000000,\n idle_timeout: 100000000,\n linger_timeout: 100000000\n ]\n]\nRun Code Online (Sandbox Code Playgroud)\n这是我通过运行以下命令在 IEX 控制台中看到的内容iex -S mix phx.server:
请注意,没有堆栈跟踪告诉我是什么终止了我的窥探会话。
\nInteractive Elixir (1.10.3) - press Ctrl+C to exit (type h() ENTER for help)\nRequest to pry #PID<0.718.0> at MyApp.Foo.foo/3 (lib/my_app/foo.ex:16)\n\n 14: \n 15: def foo(_parent, _args, %{context: %{bar: bar}}) do\n 16: require IEx; IEx.pry\n 17: \n 18: some_code()\n\nAllow? [Yn] <=== I type "Enter"\n \nInteractive Elixir (1.10.3) - press Ctrl+C to exit (type h() ENTER for help)\npry(1)> DateTime.utc_now <=== I type this to show when the pry session starts\n~U[2020-12-28 06:18:27.861251Z]\n** (EXIT from #PID<0.718.0>) shell process exited with reason: shutdown\n \n...\n \nInteractive Elixir (1.10.3) - press Ctrl+C to exit (type h() ENTER for help)\npry(1)> DateTime.utc_now\n~U[2020-12-28 06:18:40.420951Z] <== ~13 seconds, pry session dies\nRun Code Online (Sandbox Code Playgroud)\n
我发现了问题:问题出在我在单独的 JS 项目中设置的 10 秒超时。(哈哈哎呀!)我最终使用 Erlang Observer 添加了详细的跟踪,cowboys_clear并发现了有关正在发送的特定 Cowboy 错误的更多内部细节,这使我意识到它是从 JS 发起的。
CLIENT 将在 10 秒后重复关闭 HTTP 连接,导致 Cowboy(Phoenix 构建于其上)终止其 HTTP 流处理程序,这反过来又会终止 Phoenix 会话IEx.pry。
这意味着我尝试增加牛仔超时配置不会改变杀死行为。我的超时被更改但没有被触发。
:observer尽管我的 JS 问题是特定于项目的,但您可能需要从 Phoenix 应用程序中深入研究 Cowboy 的较低级别。这些
iex -S mix phx.server:observer.start()以启动 Observer GUIApplications卡,然后查找我的 Phoenix 端点(如Elixir.MyApp.Web.Endpoint)Dictionary选项卡以查找具有 of 的选项卡'$initial_call'(cowboy_clear它从 MyApp.Web.Endpoint 嵌套了 3 层)cowboy_clear节点的后代,类似于:self |> Process.info |> Keyword.get(:dictionary) |> Keyword.get(:"$ancestors")。)cowboy_clear并选择“跟踪进程树” - 我选择了所有选项。20:57:13:358740 (<0.5984.0>) exit {shutdown,{socket_error,closed,'The socket has been closed.'}}额外的思考:理论上,通过在 GraphiQL 或 Postman 中运行我的请求,我会节省大量时间,因为那里不存在超时。
cowboy_clear