Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/realtime/nodes.ex
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ defmodule Realtime.Nodes do

iex> node = :"pink@127.0.0.1"
iex> Realtime.Helpers.short_node_id_from_name(node)
"127.0.0.1"
"pink@127.0.0.1"

iex> node = :"pink@10.0.1.1"
iex> Realtime.Helpers.short_node_id_from_name(node)
Expand All @@ -124,6 +124,9 @@ defmodule Realtime.Nodes do
[_, _, _, _, _, one, two, _] ->
one <> two

["127.0.0.1"] ->
Atom.to_string(name)

_other ->
host
end
Expand Down
31 changes: 20 additions & 11 deletions lib/realtime_web/live/status_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ defmodule RealtimeWeb.StatusLive.Index do

alias Realtime.Latency.Payload
alias Realtime.Nodes
alias RealtimeWeb.Endpoint

@impl true
def mount(_params, _session, socket) do
if connected?(socket), do: RealtimeWeb.Endpoint.subscribe("admin:cluster")
{:ok, assign(socket, pings: default_pings(), nodes: Enum.count(all_nodes()))}
if connected?(socket), do: Endpoint.subscribe("admin:cluster")

socket =
socket
|> assign(nodes: Enum.count(all_nodes()))
|> stream(:pings, default_pings())

{:ok, socket}
end

@impl true
Expand All @@ -17,27 +24,29 @@ defmodule RealtimeWeb.StatusLive.Index do

@impl true
def handle_info(%Phoenix.Socket.Broadcast{payload: %Payload{} = payload}, socket) do
pair = payload.from_node <> "_" <> payload.node
payload = %{pair => payload}

pings = Map.merge(socket.assigns.pings, payload)
pair = pair_id(payload.from_node, payload.node)

{:noreply, assign(socket, pings: pings)}
{:noreply, stream(socket, :pings, [%{id: pair, payload: payload}])}
end

defp apply_action(socket, :index, _params) do
socket
|> assign(:page_title, "Status - Supabase Realtime")
|> assign(:page_title, "Realtime Status")
end

defp all_nodes do
[Node.self() | Node.list()] |> Enum.map(&Nodes.short_node_id_from_name/1)
end

defp default_pings do
for n <- all_nodes(), f <- all_nodes(), into: %{} do
pair = n <> "_" <> f
{pair, %Payload{from_node: f, latency: "Loading...", node: n, timestamp: "Loading..."}}
for n <- all_nodes(), f <- all_nodes() do
pair = pair_id(f, n)

%{id: pair, payload: %Payload{from_node: f, latency: "Loading...", node: n, timestamp: "Loading..."}}
end
end

defp pair_id(from, to) do
from <> "_" <> to
end
end
18 changes: 9 additions & 9 deletions lib/realtime_web/live/status_live/index.html.heex
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<.h1>Supabase Realtime: Multiplayer Edition</.h1>

<.h2>Cluster Status</.h2>

<p>Understand the latency between nodes across the Realtime cluster.</p>

<div class="my-5">
<div class="grid grid-cols-4 gap-12 py-4">
<%= for {_pair, p} <- @pings do %>
<div class="p-4 border-2 whitespace-nowrap overflow-hidden">
<div>From: <%= p.from_region %> - <%= p.from_node %></div>
<div>To: <%= p.region %> - <%= p.node %></div>
<div><%= p.latency %> ms</div>
<div><%= p.timestamp %></div>
</div>
<% end %>
<div id="pings" phx-update="stream" class="grid grid-cols-4 gap-12 py-4">
<div :for={{id, p} <- @streams.pings} id={id} class="p-4 border-2 whitespace-nowrap overflow-hidden">
<div>From: <%= p.payload.from_region %> - <%= p.payload.from_node %></div>
<div>To: <%= p.payload.region %> - <%= p.payload.node %></div>
<div><%= p.payload.latency %> ms</div>
<div><%= p.payload.timestamp %></div>
</div>
</div>
</div>
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Realtime.MixProject do
def project do
[
app: :realtime,
version: "2.53.1",
version: "2.53.2",
elixir: "~> 1.17.3",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
Expand Down
33 changes: 33 additions & 0 deletions test/realtime_web/live/status_live/index_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
defmodule RealtimeWeb.StatusLive.IndexTest do
use RealtimeWeb.ConnCase
import Phoenix.LiveViewTest

alias Realtime.Latency.Payload
alias Realtime.Nodes
alias RealtimeWeb.Endpoint

describe "Status LiveView" do
test "renders status page", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/status")

assert html =~ "Realtime Status"
end

test "receives broadcast from PubSub", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/status")

payload = %Payload{
from_node: Nodes.short_node_id_from_name(:"pink@127.0.0.1"),
node: Nodes.short_node_id_from_name(:"orange@127.0.0.1"),
latency: "42ms",
timestamp: DateTime.utc_now()
}

Endpoint.broadcast("admin:cluster", "ping", payload)

html = render(view)
assert html =~ "42ms"
assert html =~ "pink@127.0.0.1_orange@127.0.0.1"
end
end
end