dotfiles/app/lib/prymn_web/live/server_live/show.ex
Nikos Papadakis 26ba60b95d
app: refactor the Connection to make it asynchronous when connecting
Some work has been done on making the Connection feel nicer, but also
more work is needed to not have the channel be exposed to the upper
layers of the application. We should wrap all the GRPC calls in the
GenServer (which may also allow caching on certain calls such as
get_sys_info)
2023-08-28 23:32:42 +03:00

82 lines
2.3 KiB
Elixir

defmodule PrymnWeb.ServerLive.Show do
use PrymnWeb, :live_view
alias Prymn.{Agents, Servers}
@impl true
def mount(_params, _session, socket) do
{:ok, socket}
end
@impl true
def handle_params(%{"id" => id}, _, socket) do
server = Servers.get_server!(id)
pid = self()
if connected?(socket) and server.status == :registered do
Agents.subscribe_to_health(server.public_ip)
Agents.start_connection(server.public_ip)
Task.start_link(fn -> get_sys_info(pid, server.public_ip) end)
end
health = Agents.get_health(server.public_ip)
{:noreply,
socket
|> assign(:health, health || %{message: "Connecting..."})
|> assign(:page_title, server.name)
|> assign(:server, server)
|> assign(:uptime, 0)
|> assign(:cpus, [])
|> assign(:used_disk, 0)
|> assign(:total_memory, 0)
|> assign(:used_memory, 0)
|> assign(:registration_command, Servers.create_setup_command(server))}
end
@impl true
def handle_info(%PrymnProto.Prymn.SysInfoResponse{} = response, socket) do
{:noreply,
socket
|> assign(:uptime, response.uptime)
|> assign(
:used_memory,
bytes_to_gigabytes(response.mem_total_bytes - response.mem_avail_bytes)
)
|> assign(:total_memory, bytes_to_gigabytes(response.mem_total_bytes))
|> assign(:used_disk, calculate_disk_used_percent(response.disks))
|> assign(:cpus, response.cpus)}
end
def handle_info(%Agents.Health{} = health, socket) do
{:noreply, assign(socket, :health, health)}
end
defp bytes_to_gigabytes(bytes) do
Float.round(bytes / Integer.pow(1024, 3), 2)
end
defp calculate_disk_used_percent(disks) do
alias PrymnProto.Prymn.SysInfoResponse.Disk
{used, total} =
Enum.reduce(disks, {0, 0}, fn %Disk{} = disk, {used, total} ->
{used + disk.total_bytes - disk.avail_bytes, total + disk.total_bytes}
end)
Float.round(100 * used / total, 2)
end
defp get_sys_info(from, host_address) do
alias PrymnProto.Prymn.Agent
with {:ok, channel} <- Agents.get_channel(host_address),
{:ok, reply} <- Agent.Stub.get_sys_info(channel, %Google.Protobuf.Empty{}) do
send(from, reply)
end
Process.sleep(:timer.seconds(5))
get_sys_info(from, host_address)
end
end