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