Erlang 为什么凤凰城/牛仔城的撬壳超时如此之快?(外壳进程退出,原因为:关闭)

Erlang 为什么凤凰城/牛仔城的撬壳超时如此之快?(外壳进程退出,原因为:关闭),erlang,timeout,elixir,phoenix-framework,cowboy,Erlang,Timeout,Elixir,Phoenix Framework,Cowboy,当我使用IEx.pry或断点(通过:int.break())时,交互式shell会很快消失,在我失去会话之前,我只有大约10秒钟的时间: **(退出#PID)外壳程序进程退出,原因是:关机 10秒不足以在shell/调试器中高效地调试我的代码。我最好的猜测是,:supervisor.child\u spec中有一个默认超时,我需要覆盖它,但我不能100%确定 这就是我到目前为止所尝试的(以及为什么他们到目前为止还没有成功): 在MyApp.Application中将child_specs中的增

当我使用IEx.pry或断点(通过
:int.break()
)时,交互式shell会很快消失,在我失去会话之前,我只有大约10秒钟的时间:

**(退出#PID)外壳程序进程退出,原因是:关机

10秒不足以在shell/调试器中高效地调试我的代码。我最好的猜测是,
:supervisor.child\u spec
中有一个默认超时,我需要覆盖它,但我不能100%确定

这就是我到目前为止所尝试的(以及为什么他们到目前为止还没有成功):

  • 在MyApp.Application中将child_specs中的增加到:无穷大
  • 更新了(空闲超时、延迟超时、请求超时、关机超时),因为观察者指出我的请求是一个牛仔进程。不过,我认为不太可能是牛仔。如果默认值是60,我甚至还没有接近60
  • 我没有使用IEx.pry,而是尝试使用调试器(通过
    :ni.break
  • 注意,我不能使用
    混合测试--trace
    ,它将超时设置为:无穷大。因为我正在尝试调试一个非测试端点操作,所以这个标志没有帮助
人们如何使用调试器/IEx.pry?(我来自Ruby/JS世界,所以我喜欢有时间检查变量。)人们不会像我一样遇到10秒超时吗?或者,是否有一些常见的配置是我在故障排除方面缺少的

我的主管/孩子在应用程序中配置。例如:

注意
shutdown::infinity
配置

我的牛仔在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,
    ]
  ]
牛仔配置控制台检查

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,
    ]
  ]
这只是为了确认我在正确的地方配置了牛仔。我确认切换端口确实会影响端口

这是我通过运行
IEX-S mix phx.server在IEX控制台中看到的内容

请注意,没有stacktrace告诉我是什么杀死了我的pry会话

Interactive Elixir(1.10.3)-按Ctrl+C退出(输入h()获取帮助)
请求在MyApp.Foo.Foo/3(lib/my#u app/Foo.ex:16)上查询PID
14: 
15:def foo(_parent,_args,%%{context:%%{bar:bar})do
16:需要IEx;撬动
17: 
18:some_code()
允许吗?[Yn]DateTime.utc\u现在DateTime.utc\u现在

~U[2020-12-28 06:18:40.420951Z]我发现了问题:问题出在我在一个单独的JS项目中设置的10秒超时内。(哈哈哦!)我最终使用Erlang Observer在
cowboys\U clear
上添加了详细的跟踪,并找到了有关发送的特定Cowboy错误的更多内部细节,这让我意识到它是由JS发起的

解释JS(ie客户端)超时如何影响cowboy/Phoenix调试 客户端将在10秒后重复关闭HTTP连接,导致Cowboy(Phoenix是在其上构建的)杀死其HTTP流处理程序,进而杀死Phoenix
IEx.pry
会话

这意味着我增加牛仔超时配置的尝试不会改变杀戮行为。我的超时正在更改,但没有被触发

如何通过Erlang的
:observer解决牛仔超时问题
虽然我的JS问题是特定于项目的,但您可能需要从Phoenix应用程序中深入了解较低级别的Cowboy。这些

  • 运行Phoenix应用程序
    iex-S mix phx.server
  • 运行
    :observer.start()
    以启动observer GUI
  • 单击
    Applications
    选项卡,查找我的Phoenix端点(如
    Elixir.MyApp.Web.endpoint
  • 右键单击其子项,单击每个子项的
    字典
    选项卡,找到一个具有
    牛仔清除
    'initial\u call'
    (它嵌套在MyApp.Web.Endpoint的3层深处)
  • (在这里,我能够确认我触发的Pry断点是这个
    cowboy\u clear
    节点的后代,具有类似于:
    self>Process.info>Keyword.get(:dictionary);>Keyword.get(:“$祖先”)
  • 右键单击
    cowboy\u clear
    并选择“跟踪流程树”-我选择了所有选项
  • 将选项卡更改为“跟踪概述”,选择pid,然后单击“开始跟踪”
  • 等待牛仔死亡,并将跟踪保存到文本文件中
  • 搜索“退出”、“关机”或类似的内容
  • 在我的例子中,我发现
    20:57:13:358740()退出{shutdown,{socket_error,closed,'socket已经关闭。}
  • 在这一点上,我猜是JS b/c Cowboy似乎不是触发请求关闭的那个
  • 额外思考:理论上,我可以通过在GraphiQL或Postman中运行请求来节省大量时间,因为那里不存在超时

    有用资源
    • -我在调试模式下运行了mix phx.server,并在IEx提示符下运行了observer命令
    • -这有助于理解流程结构,因此我可以猜测我需要跟踪
      cowboy\u clear
    • -长生不老药配置说明
    • -这些是我在意识到它是JS之前切换的牛仔超时配置

    请共享完整的堆栈跟踪。@AlekseiMatiushkin我用控制台输出更新了原始日志,但不幸的是没有任何堆栈跟踪!这也是我被难倒的部分原因。我对elixir/pry不太了解,但外壳会死亡,因为它与进程相关:由于进程在
    shutdown
    时退出(可能是缺少堆栈跟踪的原因),它会发出相同的信号,因此外壳在
    shutdown
    时退出。该过程可能会从多个sourc接收到
    关闭
    信号
    iex(4)> MyApp.Web.Endpoint.config(:http)
    [
      port: 4001,
      protocol_options: [
        request_timeout: 100000000,
        shutdown_timeout: 100000000,
        idle_timeout: 100000000,
        linger_timeout: 100000000
      ]
    ]
    
    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