mtrudel/bandit

Plug.Conn.chunk does not send the chunk to client

xshadowlegendx opened this issue · 3 comments

Hello my phoenix app has an endpoint for user to subscribe to and get a stream of data back over time, it worked before using cowboy adapter but it does not work after switching to use bandit adapter, I logged the return of chunk/2 and it looks like it is working but it is not.

After the client connects to the endpoint, it waits indefinitely and receives no data back. Below is the log

2024-03-22T15:38:36.460Z,[INFO]: Chunked 200 in 103ms
{:ok,
 %Plug.Conn{
   adapter: {Bandit.HTTP1.Adapter, :...},
   assigns: %{},
   body_params: %{},
   cookies: %Plug.Conn.Unfetched{aspect: :cookies},
   halted: false,
   host: "localhost",
   method: "GET",
   owner: #PID<0.5005.0>,
   params: %{
     "merchant_id" => "1",
     "transaction_id" => "f5726640-1226-446a-9fc3-39e101e7ecce"
   },
   path_info: ["api", "user", "get_notify_on_progress"],
   path_params: %{},
   port: 4000,
   private: %{
     :user => %{},
     MyAppWeb.Router => [],
     :plug_session_fetch => #Function<1.76384852/1 in Plug.Session.fetch_session/1>,
     :before_send => [#Function<0.54455629/1 in Plug.Telemetry.call/2>],
     :phoenix_endpoint => MyAppWeb.Endpoint,
     :phoenix_router => MyAppWebWeb.Router,
     :phoenix_format => "json"
   },
   query_params: %{
     "merchant_id" => "1",
     "transaction_id" => "f5726640-1226-446a-9fc3-39e101e7ecce"
   },
   query_string: "merchant_id=1&transaction_id=f5726640-1226-446a-9fc3-39e101e7ecce",
   remote_ip: {127, 0, 0, 1},
   req_cookies: %Plug.Conn.Unfetched{aspect: :cookies},
   req_headers: [
     {"sec-fetch-site", "same-origin"},
     {"sec-fetch-mode", "cors"},
     {"sec-fetch-dest", "empty"},
     {"cookie",
      "csrftoken=k7c26Fow3gCkeScDkoZaFXVMyGTvP6B5; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19LNG05sNFFBqAXXNCIlNn%2Fx85AdL1hQWnQN2KI3PLjY2ntovdTzct7MyTsDywCwROomNp0QlX%2FCg%3D%3D; rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2BYfPZGNTNZs6lsJSo0NTdXrgL9wtDXdVk%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX19aCHDTVKdRvpIMh6FC%2FWXFGiFDY9cridQ%3D; MMUSERID=ohjntuxmg7gwxn8z9ztu1dzpfh; MMCSRF=a6gqxg1qgtb6pkdibkny1f84za; MMAUTHTOKEN=bbbhphunqjy3dg4unjueedn88y; rl_user_id=RudderEncrypt%3AU2FsdGVkX1%2FMMutUQ86kPj3bBwNCV%2B4Wy%2FHTNcxjNsGJ67WAOtt7hw2%2Fpngdzh3K; rl_trait=RudderEncrypt%3AU2FsdGVkX19hYLEpncOhCyQYcmeMQQFeYl5G6Qt%2FVc4%3D"},
     {"connection", "keep-alive"},
     {"dnt", "1"},
     {"x-user-id", "1c1d6cda-e8f0-4937-a94a-ddf594321b72"},
     {"accept-encoding", "gzip, deflate, br"},
     {"accept-language", "en-US,en;q=0.5"},
     {"accept", "*/*"},
     {"user-agent",
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:123.0) Gecko/20100101 Firefox/123.0"},
     {"host", "localhost:4000"}
   ],
   request_path: "/api/user/get_notify_on_progress",
   resp_body: nil,
   resp_cookies: %{},
   resp_headers: [
     {"cache-control", "no-store"},
     {"x-request-id", "F78JZdKGNMG1mHwAAHCC"},
     {"content-type", "text/event-stream; charset=utf-8"}
   ],
   scheme: :http,
   script_name: [],
   secret_key_base: :...,
   state: :chunked,
   status: 200
 }}

here is the handler for the endpoint

defmodule MyAppWeb.SubscribeForProgress do
  alias MyApp.Account

  def subscribe_for_progress(conn, %{"user_id" => user_id, "transaction_id" => transaction_id}) do
    with :ok <- Account.get_notify_about_progress(user_id, transaction_id),
      conn <- prepare_sse_conn(conn),
      {:ok, conn} <- wait_for_progress_notify(conn)
    do
      conn
    end
  end

  defp prepare_sse_conn(conn) do
    conn
    |> Plug.Conn.put_resp_content_type("text/event-stream")
    |> Plug.Conn.put_resp_header("cache-control", "no-store")
    |> Plug.Conn.send_chunked(200)
  end

  defp wait_for_payment_progress_notify(conn) do
    # Plug.Conn.chunk(conn, "hello") |> IO.inspect()
    # Plug.Conn.chunk(conn, "world") |> IO.inspect()

    receive do
      {:transaction_done, payload} -> Plug.Conn.chunk(conn, Jason.encode!(payload))

      {:plug_conn, :sent} -> wait_for_payment_progress_notify(conn)
    end
  end
end

sorry there was a typo bug on my side, closing this

Curious; were you missing a place
Where you should have been grabbing the conn from a function return?

Curious; were you missing a place Where you should have been grabbing the conn from a function return?

hello, so the get_notify_about_progress function just call phoenix pubsub to subscribe a topic and there was typo in the topic name that's y I did not getting any messages