I was recently experimenting with the possibility of retaining a channel instance’s state (assigns) between crashes.
In my testing application, I am causing the channel instance to crash and I noticed that the instance is not automatically restarted. It seems that channel instances are not supervised.
Why is it the case? Do we rely on the channel’s client to reestablish a connection thus creating a new channel instance on the server side?
DETAILS
Here is the code for the channel and the test that I am using:
defmodule ChanState.KablamChannel do
use ChanState.Web, :channel
def join("kablam", payload, socket) do
{:ok, assign(socket, :ns, [])}
end
def handle_in("add", %{"n" => n}, socket) do
ns = socket.assigns[:ns]
{:noreply, assign(socket, :ns, ns ++ [n])}
end
def handle_in("get", _, socket) do
ns = socket.assigns[:ns]
{:reply, {:ok, %{"ns" => ns}}, socket}
end
def handle_in("oopsy", _, socket) do
a = 1 / 0
{:noreply, socket}
end
end
TEST:
defmodule ChanState.KablamChannelTest do
use ChanState.ChannelCase
alias ChanState.KablamChannel
setup do
{:ok, _, socket} =
socket()
|> subscribe_and_join(KablamChannel, "kablam")
{:ok, socket: socket}
end
test "main", %{socket: socket} do
Process.unlink(socket.channel_pid)
push socket, "add", %{"n" => 2149}
push socket, "add", %{"n" => 1234}
ref = push socket, "get", %{}
assert_reply ref, :ok, %{"ns" => [2149, 1234]}
push socket, "oopsy", %{}
ref = push socket, "get", %{}
## The following returns undefined
IO.inspect(:erlang.process_info(socket.channel_pid))
assert_reply ref, :ok, %{"ns" => []}, 5000
end
end