Skip to content

Commit

Permalink
Push proper close event on dup topic shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
chrismccord committed Jun 9, 2021
1 parent 434f3d6 commit 4a27e93
Showing 1 changed file with 18 additions and 13 deletions.
31 changes: 18 additions & 13 deletions lib/phoenix/socket.ex
Original file line number Diff line number Diff line change
Expand Up @@ -487,15 +487,7 @@ defmodule Phoenix.Socket do
end

def __info__({:socket_close, pid, _reason}, {state, socket}) do
case state.channels_inverse do
%{^pid => {topic, join_ref}} ->
{^pid, monitor_ref} = Map.fetch!(state.channels, topic)
state = delete_channel(state, pid, topic, monitor_ref)
{:push, encode_close(socket, topic, join_ref), {state, socket}}

%{} ->
{:ok, {state, socket}}
end
socket_close(pid, {state, socket})
end

def __info__(:garbage_collect, state) do
Expand Down Expand Up @@ -630,20 +622,21 @@ defmodule Phoenix.Socket do
end
end

defp handle_in({pid, ref}, %{event: "phx_join", topic: topic} = message, state, socket) do
defp handle_in({pid, _ref}, %{event: "phx_join", topic: topic} = message, state, socket) do
receive do
{:socket_close, ^pid, _reason} -> :ok
after
0 ->
Logger.debug(fn ->
"Duplicate channel join for topic \"#{topic}\" in #{inspect(socket.handler)}. " <>
"Closing existing channel for new join."
"Closing existing channel for new join."
end)
end

:ok = shutdown_duplicate_channel(pid)
state = delete_channel(state, pid, topic, ref)
handle_in(nil, message, state, socket)
{:push, {opcode, payload}, {new_state, new_socket}} = socket_close(pid, {state, socket})
send(self(), {:socket_push, opcode, payload})
handle_in(nil, message, new_state, new_socket)
end

defp handle_in({pid, _ref}, message, state, socket) do
Expand Down Expand Up @@ -722,4 +715,16 @@ defmodule Phoenix.Socket do
receive do: ({:DOWN, ^ref, _, _, _} -> :ok)
end
end

defp socket_close(pid, {state, socket}) do
case state.channels_inverse do
%{^pid => {topic, join_ref}} ->
{^pid, monitor_ref} = Map.fetch!(state.channels, topic)
state = delete_channel(state, pid, topic, monitor_ref)
{:push, encode_close(socket, topic, join_ref), {state, socket}}

%{} ->
{:ok, {state, socket}}
end
end
end

0 comments on commit 4a27e93

Please sign in to comment.