我在 HTTP 端点后面有具有复杂业务逻辑的 Phoenix 应用程序。该逻辑包括与数据库和少量外部服务的交互,一旦请求处理开始,在所有操作完成之前不得中断。
但是,如果客户端突然关闭连接,这似乎会导致 Cowboy 或 Ranch 杀死请求处理程序进程(Phoenix 控制器),从而导致部分执行的业务流程。为了调试这个,我在控制器操作中有以下代码:
Process.flag(:trap_exit, true)
receive do
msg -> Logger.info("Message: #{inspect msg}")
after
10_000 -> Logger.info("Timeout")
end
为了模拟连接关闭,我设置了 timeout: curl --request POST 'http://localhost:4003' --max-time 3
。在 IEx 控制台 3 秒后,我看到该进程即将退出:Message: {:EXIT, #PID<0.4196.0>, :shutdown}
.
所以我需要让控制器完成它的工作并在它仍然存在时回复客户端,或者如果连接丢失则什么都不做。这将是实现这一目标的最佳方法:
- 在控制器操作中捕获退出并忽略退出消息;
- spawn 未
Task
在控制器操作中链接并等待其结果; - 以某种方式配置 Cowboy/Ranch 以便它不会杀死处理程序进程,如果可能的话(尝试
exit_on_close
没有运气)?