gpt4 book ai didi

erlang - 当客户端关闭连接时,Cowboy/Ranch 会终止处理程序进程

转载 作者:行者123 更新时间:2023-12-04 15:00:27 25 4
gpt4 key购买 nike

我的 Phoenix 应用程序在 HTTP 端点后面具有复杂的业务逻辑。该逻辑包括与数据库和少量外部服务的交互,一旦请求处理开始,在所有操作完成之前不得中断。
但是,如果客户端突然关闭连接,则似乎 Cowboy 或 Ranch 会杀死请求处理程序进程(Phoenix Controller ),从而导致部分执行的业务流程。为了调试这个,我在 Controller 操作中有以下代码:

Process.flag(:trap_exit, true)

receive do
msg -> Logger.info("Message: #{inspect msg}")
after
10_000 -> Logger.info("Timeout")
end
为了模拟连接关闭,我设置了超时: curl --request POST 'http://localhost:4003' --max-time 3 .
在 IEx 控制台中 3 秒后,我看到该进程即将退出: Message: {:EXIT, #PID<0.4196.0>, :shutdown} .
所以我需要让 Controller 完成它的工作并在它仍然存在时回复客户端,或者如果连接丢失则什么都不做。这将是实现这一目标的最佳方式:
  • 在 Controller 操作中陷阱退出并忽略退出消息;
  • 生成未链接 Task在 Controller 操作中并等待其结果;
  • 如果可能的话,以某种方式配置 Cowboy/Ranch 使其不会杀死处理程序进程(尝试 exit_on_close 但没有运气)?
  • 最佳答案

    处理进程会在请求结束后被杀死,这就是它们的目的。如果你想在后台处理一些数据,那就开始额外的处理。最简单的方法是您提出的第二种方法,但对使用 Task.Supervisor 稍作修改。 .
    所以在你的应用程序主管你开始 Task.Supervisor使用您选择的名称:

    children = [
    {Task.Supervisor, name: MyApp.TaskSupervisor}
    ]

    Supervisor.start_link(children, strategy: :one_for_one)
    然后在您的请求处理程序中:
    parent = self()
    ref = make_ref()

    Task.Supervisor.start_child(MyApp.TaskSupervisor, fn() ->
    send(parent, {ref, do_long_running_stuff()})
    end)

    receive do
    {^ref, result} -> notify_user(result)
    end
    这样您就不必担心用户不在那里接收消息时的处理情况。

    关于erlang - 当客户端关闭连接时,Cowboy/Ranch 会终止处理程序进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67021302/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com