DBConnection.ConnectionError PID(XXX) 退出一些 sql 查询

DBConnection.ConnectionError PID(XXX) exited for some sql queries

我目前正在为这个错误而苦苦挣扎,因为我的服务器没有提供太多日志和信息。我有一个名为 /stop 的端点(下面提供了代码示例),在返回 :ok 之前,我在其中执行了很多代码。所有这些代码都包含在多个函数中,并通过多个文件和服务。

离这些函数结束不远了,我正在写入数据库。我有 3 个不同的插件。但是几天后,我遇到了这个错误:Postgrex.Protocol (#PID<0.375.0>) disconnected: ** (DBConnection.ConnectionError) client #PID<0.543.0> exited 随机出现在这 3 个插入内容之一中。 (它可能是第一个,它可能在第二个中间,或者最后一个。有时(很少)它甚至不会失败)。我唯一能够隔离为 "trigger" 的是当插入的数据稍大时。它以前一直有效,当我试图通过 iex 直接插入那些相同的数据时,它也工作得很好。

在 Postgres 方面,我只有这个日志:LOG: unexpected EOF on client connection with an open transaction

控制器代码如下所示:

  def stop(conn, params) do
        case @influx_caller.end_connexion_performable?(params) do
          true ->
            handle_end_of_connexion(params)
            conn |> send_resp(:ok, [])

          false ->
            if @influx_caller.connexion_data_from(params["connexion_key"]) == %{} do
              update_connexion_with(:influx_empty, params, true)
            end

            conn |> send_resp(:forbidden, [])
        end
      end
    end
  end

故障发生在 handle_end_of_connexion 函数调用的其中一个文件的正常路径(案例的真实选项)中。例如在这个查询中:

Ecto.Changeset.change(connexion, %{
        closed_at: Calculation.get_close_time(events),
      })
      |> Ecto.Changeset.put_assoc(:infos, MyApp.InfosGenerator.perform(obj, obj_type, twi, twl, events))
      |> MyApp.Repo.update

可以从我的应用程序(类似于管理面板)中的另一个控制器调用具有完全相同数据的完全相同的文件,并且它工作得很好。所以我认为我的问题来自 /stop 端点。

到目前为止我测试过的东西:

None 的作品。 (当然,我也试过到处记录,但在本地模式下一切正常)

任何帮助或至少引导将不胜感激。提前致谢!

[编辑] 感谢观察者,我设法收集了这些额外信息:

发生此错误时:Postgrex.Protocol (#PID<0.422.0>) disconnected: ** (DBConnection.ConnectionError) client #PID<0.31212.0> exited,我在观察器中弹出这些行 =>

11:06:52:783159 (<0.31212.0>) out {lists,reverse,1}
11:06:52:783212 (<0.31212.0>) in {lists,reverse,1}
11:06:52:783218 (<0.31212.0>) << {inet_reply,#Port<0.71>,ok}
11:06:52:783234 (<0.31212.0>) out {prim_inet,send_recv_reply,2}
11:06:52:783243 (<0.31212.0>) in {prim_inet,send_recv_reply,2}
11:06:52:783247 (<0.31212.0>) out {prim_inet,recv0,3}
11:06:52:797698 (<0.31209.0>) in {cowboy_http,loop,1}
11:06:52:797725 (<0.31209.0>) << {tcp_closed,#Port<0.140>}
11:06:52:797750 (<0.31209.0>) getting_unlinked #Port<0.140>
11:06:52:797786 (<0.31209.0>) out {cowboy_children,terminate_loop,2}
11:06:52:797794 (<0.31212.0>) in {prim_inet,recv0,3}
11:06:52:797800 (<0.31212.0>) exit shutdown
11:06:52:797820 (<0.31212.0>) out_exited 0
11:06:52:797905 (<0.31209.0>) in {cowboy_children,terminate_loop,2}
11:06:52:797911 (<0.31209.0>) getting_unlinked <0.31212.0>
11:06:52:797915 (<0.31209.0>) << {'EXIT',<0.31212.0>,shutdown}
11:06:52:797943 (<0.31209.0>) exit {shutdown,{socket_error,closed,'The socket has been closed.'}}
11:06:52:797951 (<0.31209.0>) out_exited 0

进程在此处产生:

11:06:52:304313 (<0.31209.0>) spawn <0.31212.0> as proc_lib:init_p(<0.31209.0>,[<0.447.0>,<0.446.0>,'Elixir.Tracking.Endpoint',<0.414.0>,<0.413.0>],cowboy_stream_h,request_process,[#{body_length => 136,cert => undefined,has_body => true, [etc...]

我真的不明白什么以及为什么这个进程被关闭并且link丢失了:/

事实证明,自最近的牛仔更新以来,请求超时的处理方式有所不同。我发现最好(也是最干净)的解决方法是将调用我的控制器后所做的所有操作包装到一个全新的进程中。