Registry: How to get notified about a crashed process after a LiveView refresh?

I’m doing some experimentation, and I ran into an issue with my Registry setup.

I have an event where I start some doomed tasks:

def handle_event("start_processes", _, socket) do
  for _ <- 1..5 do
    name = :rand.bytes(5) |> Base.url_encode64(padding: false)

    task =
      TaskSupervisor
      |> Task.Supervisor.async_nolink(fn ->
        Process.sleep(to_timeout(second: :rand.uniform(9)))
        raise "Crash!"
      end)

    Registry.register(ProcessesRegistry, name, task.pid)

    task
  end
  processes = Registry.select(ProcessesRegistry, registry_select_all())
  {:noreply, assign(socket, processes: processes)}
end

I’d like to update my LiveView about the status of these tasks:

<div>
  <p>Current process: {inspect(self())}</p>
  <p>Registry process: {inspect(Process.whereis(ProcessesRegistry))}</p>

  <.button phx-click="get_registered_processes">Refresh Processes</.button>
  <.button phx-click="start_processes">Start Processes</.button>

  <h2>Background Processes</h2>
  <%= for pid <- @processes do %>
    <div>PID: {inspect(pid)}</div>
  <% end %>
</div>
def handle_info({:DOWN, _ref, :process, pid, _reason}, socket) do
  IO.puts("handling DOWN message in #{inspect(socket.root_pid)}")

  [{key, {_, _}}] = Registry.select(ProcessesRegistry, [{{:_, :_, pid}, [], [:"$_"]}])
  Registry.unregister(ProcessesRegistry, key)

  processes = Registry.select(ProcessesRegistry, registry_select_all())
  {:noreply, assign(socket, processes: processes)}
end

But there is a very simple problem: what happens when the LiveView page is refreshed?

The PID of the LiveView is changed, which causes the :DOWN messages to be sent to the old LiveView process instead of the new one.

Is there a simple way to solve this problem?

Thanks :smiley:

You could use PubSub and broadcast the result of the task. Use the session id in the topic. Just make sure your LV subscribes to that topic on mount.

And to add on to this, you could also use user id in the topic if you want it to work across sessions/browsers/devices.