Genserver Phoenix 问题

问题描述

我从端点获取数据作为列表,假设它们是唯一的 ID 我尝试为每个进程启动一个 GenServer 进程,但进程在启动后立即终止,但错误不清楚,我似乎无法找到杀死进程的原因,这是我下面的示例代码和尝试调试的错误。注意(“但是,我可以使用单个事务启动一个进程”,当我使用 ID 调用 Enum.each() 并尝试在命令行中启动 GenServer 时,它也可以成功运行)。当列表来自端点时究竟发生了什么,因为可以清楚地打印并且进程成功启动但它们也立即终止?。

def new(conn,%{"hashes" => [_ | _] = hashes}) do
    # Enum.each the list of hashes call hash fn on each hash
    # needs more debugging the function is glitching "some processes failing"
    hashes
    |>Enum.each(fn hash ->  call_hash(conn,hash) end)  #research more queing calls?
  end


  defp call_hash(conn,hash) do
    with {:ok,_} <- GenServer.start_link(TransactionSubscriptionHandler,%{hash: 
  String.to_atom(hash)},name: String.to_atom(hash))
        #  {:ok,%{status: 200}} <- BlockNative.subscribe_transaction(hash)
         do
         json(conn,%{status: "Ok"})
        else
     _ -> conn |> put_status(400) |> json(%{status: "Failed"})
  end

  end

输入

"hashes": [
        "0x04b08ab13d51613975cd5035cebb52d5f574137c42902a5b1147f953f1895c6a","0x2285dfeafe2eae5846fe66bd9631f2d258c1d5b32702649153c9073a3a4ec8ad"
    ]

命令行输出

[info] POST /api/transaction
[debug] Processing with VhsWeb.TransactionController.new/2
  Parameters: %{"hashes" => ["0x04b08ab13d51613975cd5035cebb52d5f574137c42902a5b1147f953f1895c6a","0x2285dfeafe2eae5846fe66bd9631f2d258c1d5b32702649153c9073a3a4ec8ad"]}
  Pipelines: [:api]
{:ok,#PID<0.597.0>}
[info] Sent 200 in 2ms
{:ok,#PID<0.598.0>}
[info] Sent 200 in 2ms
[error] Ranch listener VhsWeb.Endpoint.HTTP had connection process started with :cowboy_clear:start_link/4 at #PID<0.594.0> exit with reason: {:function_clause,[{:cowboy_http,:commands,[{:state,#PID<0.471.0>,VhsWeb.Endpoint.HTTP,#Port<0.22>,:ranch_tcp,:undefined,%{env: %{dispatch: [{:_,[],[{:_,Phoenix.Endpoint.Cowboy2Handler,{VhsWeb.Endpoint,[]}}]}]},stream_handlers: [:cowboy_telemetry_h,:cowboy_stream_h]},"",%{},{{127,1},34624},4000},#Reference<0.3145460136.2965635073.81437>,2,{:ps_request_line,0},:infinity,1,:done,100,[{:stream,{:cowboy_telemetry_h,{:state,{:cowboy_stream_h,#PID<0.595.0>,:fin,180,...}},#Function<0.122385210/1 in :cowboy_telemetry_h."-fun.metrics_callback/1-">,%{body_length: 180,cert: :undefined,has_body: true,headers: %{"accept" => "*/*","accept-encoding" => "gzip,deflate,br","connection" => "keep-alive","content-length" => "180","content-type" => "application/json","host" => "localhost:4000","postman-token" => "ad48096e-c775-4f82-a860-a4d4b4286c9c","user-agent" => "PostmanRuntime/7.26.8"},host: "localhost",method: "POST",path: "/api/transaction",peer: {{127,...},pid: #PID<0.594.0>,port: 4000,qs: "",ref: VhsWeb.Endpoint.HTTP,"200 OK",%{"cache-control" => "max-age=0,private,must-revalidate","content-length" => "15","content-type" => "application/json; charset=utf-8","date" => "Mon,03 May 2021 20:41:43 GMT","server" => "Cowboy","x-request-id" => "FnupLbYol1vbVZsAAABE"},-576460686234141769,-576460686234115433,-576460686203746015,%{#PID<0.595.0> => %{spawn: -576460686234129902}},"POST",:"HTTP/1.1",[]}],[{:child,5000,:undefined}]},[{:response,["{\"",[[] | "status"],"\":",[34,[[] | "Ok"],34],125]}]],[file: '/home/edwin/dev/phoenix-projects/vhs/deps/cowboy/src/cowboy_http.erl',line: 922]},{:cowboy_http,:loop,line: 231]},{:proc_lib,:init_p_do_apply,3,[file: 'proc_lib.erl',line: 226]}]}

解决方法

许多进程与该问题无关。这是会引发相同错误的简化代码。

def new(conn,_),do: ["1","2"] |> Enum.each(&call_hash(conn,&1))

defp call_hash(conn,_) do
  json(conn,%{status: "Ok"})
end

也就是说,您正在尝试向单个 POST 请求发送多个响应,这显然失败了,因为 conn 在发送第一个响应后终止。