Skip to content

Commit

Permalink
Allow to not block the channel supervisor on join
Browse files Browse the repository at this point in the history
  • Loading branch information
José Valim committed Mar 7, 2019
1 parent 6139356 commit 8e23c3d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 10 deletions.
24 changes: 20 additions & 4 deletions lib/phoenix/channel/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,25 @@ defmodule Phoenix.Channel.Server do

case PoolSupervisor.start_child(socket.endpoint, socket.handler, from, args) do
{:ok, :undefined} ->
receive do: ({^ref, reply} -> {:error, reply})
receive do: ({^ref, {:error, reply}} -> {:error, reply})

{:ok, pid} ->
receive do: ({^ref, reply} -> {:ok, reply, pid})
mon_ref = Process.monitor(pid)

receive do
{^ref, {:ok, reply}} ->
Process.demonitor(mon_ref, [:flush])
{:ok, reply, pid}

{^ref, {:error, reply}} ->
Process.demonitor(mon_ref, [:flush])
{:error, reply}

{:DOWN, ^mon_ref, _, _, reason} ->
Logger.error fn -> Exception.format_exit(reason) end
{:error, %{reason: "join crashed"}}
end

{:error, reason} ->
Logger.error fn -> Exception.format_exit(reason) end
{:error, %{reason: "join crashed"}}
Expand Down Expand Up @@ -207,7 +223,7 @@ defmodule Phoenix.Channel.Server do
init(socket, channel, topic, reply, from)
{:error, reply} ->
log_join socket, topic, fn -> "Replied #{topic} :error" end
GenServer.reply(from, reply)
GenServer.reply(from, {:error, reply})
:ignore
other ->
raise """
Expand Down Expand Up @@ -238,7 +254,7 @@ defmodule Phoenix.Channel.Server do
PubSub.subscribe(pubsub_server, topic, link: true, fastlane: fastlane)

log_join socket, topic, fn -> "Replied #{topic} :ok" end
GenServer.reply(from, reply)
GenServer.reply(from, {:ok, reply})
{:ok, %{socket | joined: true}}
end

Expand Down
6 changes: 3 additions & 3 deletions lib/phoenix/socket.ex
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@ defmodule Phoenix.Socket do
{auth_payload, from, socket}
A custom channel implementation MUST invoke
`GenServer.reply(from, reply_payload)` during its initialization
with a custom `reply_payload` that will be sent as a reply to the
client. Failing to do so will block the socket forever.
`GenServer.reply(from, {:ok | :error, reply_payload})` during its
initialization with a custom `reply_payload` that will be sent as
a reply to the client. Failing to do so will block the socket forever.
A custom channel receives `Phoenix.Socket.Message` structs as regular
messages from the transport. Replies to those messages and custom
Expand Down
11 changes: 8 additions & 3 deletions test/phoenix/integration/websocket_channels_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ defmodule Phoenix.Integration.WebSocketChannelsTest do
def init({payload, from, socket}) do
case payload["action"] do
"ok" ->
GenServer.reply(from, %{"action" => "ok"})
GenServer.reply(from, {:ok, %{"action" => "ok"}})
{:ok, socket}

"ignore" ->
GenServer.reply(from, %{"action" => "ignore"})
:ignore
GenServer.reply(from, {:error, %{"action" => "ignore"}})
send(self(), :stop)
{:ok, socket}

"error" ->
raise "oops"
Expand All @@ -86,6 +87,10 @@ defmodule Phoenix.Integration.WebSocketChannelsTest do
send socket.transport_pid, {:socket_close, self(), :shutdown}
{:stop, :shutdown, socket}
end

def handle_info(:stop, socket) do
{:stop, :shutdown, socket}
end
end

defmodule UserSocketConnectInfo do
Expand Down

0 comments on commit 8e23c3d

Please sign in to comment.