LiveView PubSub Subscription Issue
efleming opened this issue · 3 comments
efleming commented
I have a LiveView page I am working with, the page has a subscription to a PubSub topic to receive updates. I have a handle_info callback defined for the subscription. When using cowboy, this all works fine, when using Bandit (bandit 1.0.0-pre.16
) I receive an error:
[error] GenServer #PID<0.6749.0> terminating
** (FunctionClauseError) no function clause matching in Bandit.HTTP1.Handler.handle_info/2
(bandit 1.0.0-pre.16) project/deps/thousand_island/lib/thousand_island/handler.ex:5: Bandit.HTTP1.Handler.handle_info({Project.Accounts, [:user, :updated], #Project.Accounts.User<__meta__: #Ecto.Schema.Metadata<:loaded, "users">, id: 9, org_id: 3, org: %Project.Orgs.Org{__meta__: #Ecto.Schema.Metadata<:loaded, "orgs">, id: 3, parent_path: "1.2", parent: #Ecto.Association.NotLoaded<association :parent is not loaded>, name: "My Org", path: "1.2.3", inserted_at: ~N[2023-10-06 20:35:08], updated_at: ~N[2023-10-11 15:30:49]}, first_name: "FirstName", last_name: "LastName", email: "firstlast@email.com", phone_number: "5555551111", confirmed_at: nil, inserted_at: ~N[2023-10-12 15:34:42], updated_at: ~N[2023-10-12 16:23:20], ...>}, {%ThousandIsland.Socket{socket: #Port<0.29>, transport_module: ThousandIsland.Transports.TCP, read_timeout: 60000, span: %ThousandIsland.Telemetry{span_name: :connection, telemetry_span_context: #Reference<0.3702468754.2544107526.246215>, start_time: -576459807178663489, start_metadata: %{telemetry_span_context: #Reference<0.3702468754.2544107526.246215>, remote_address: {127, 0, 0, 1}, remote_port: 60848, parent_telemetry_span_context: #Reference<0.3702468754.2544107521.249876>}}}, %{opts: %{http_1: [], http_2: [], websocket: []}, plug: {Phoenix.Endpoint.SyncCodeReloadPlug, {ProjectWeb.Endpoint, []}}, handler_module: Bandit.HTTP1.Handler, http_1_enabled: true, http_2_enabled: true, websocket_enabled: true, requests_processed: 9}})
(stdlib 5.0.2) gen_server.erl:1077: :gen_server.try_handle_info/3
(stdlib 5.0.2) gen_server.erl:1165: :gen_server.handle_msg/6
(stdlib 5.0.2) proc_lib.erl:241: :proc_lib.init_p_do_apply/3
Last message: {Project.Accounts, [:user, :updated], #Project.Accounts.User<__meta__: #Ecto.Schema.Metadata<:loaded, "users">, id: 9, org_id: 3, org: %Project.Orgs.Org{__meta__: #Ecto.Schema.Metadata<:loaded, "orgs">, id: 3, parent_path: "1.2", parent: #Ecto.Association.NotLoaded<association :parent is not loaded>, name: "My Org", path: "1.2.3", inserted_at: ~N[2023-10-06 20:35:08], updated_at: ~N[2023-10-11 15:30:49]}, first_name: "FirstName", last_name: "LastName", email: "firstlast@email.com", phone_number: "5555551111", confirmed_at: nil, inserted_at: ~N[2023-10-12 15:34:42], updated_at: ~N[2023-10-12 16:23:20], ...>}
State: {%ThousandIsland.Socket{socket: #Port<0.29>, transport_module: ThousandIsland.Transports.TCP, read_timeout: 60000, span: %ThousandIsland.Telemetry{span_name: :connection, telemetry_span_context: #Reference<0.3702468754.2544107526.246215>, start_time: -576459807178663489, start_metadata: %{telemetry_span_context: #Reference<0.3702468754.2544107526.246215>, remote_address: {127, 0, 0, 1}, remote_port: 60848, parent_telemetry_span_context: #Reference<0.3702468754.2544107521.249876>}}}, %{opts: %{http_1: [], http_2: [], websocket: []}, plug: {Phoenix.Endpoint.SyncCodeReloadPlug, {ProjectWeb.Endpoint, []}}, handler_module: Bandit.HTTP1.Handler, http_1_enabled: true, http_2_enabled: true, websocket_enabled: true, requests_processed: 9}}
Here is a an excerpt from the LiveView:
defmodule Project.UserLive.Index do
@moduledoc false
use ProjectWeb, :live_view
alias Project.Accounts
alias Project.Accounts.User
@impl true
def mount(params, _session, socket) do
Accounts.subscribe()
{:ok, socket}
end
@impl true
def handle_info({Project.Accounts, [:user | _], _}, socket) do
{:noreply, socket}
end
end
Here is an excerpt of where the events get fired (Project.Accounts):
defmodule Project.Accounts do
@topic inspect(__MODULE__)
def subscribe do
Phoenix.PubSub.subscribe(Project.PubSub, @topic)
end
def delete_user(%User{} = user) do
user
|> Repo.delete()
|> broadcast_change([:user, :deleted])
end
defp broadcast_change({:ok, result}, event) do
Phoenix.PubSub.broadcast(Project.PubSub, @topic, {__MODULE__, event, result})
{:ok, result}
end
end
mtrudel commented
mtrudel commented
No problem! Happy to help!