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)
82 lines
2.3 KiB
Elixir
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
|