defmodule PrymnWeb.SystemInfo do use PrymnWeb, :live_component require Logger alias Phoenix.LiveView.AsyncResult @impl true def update(assigns, socket) do {:ok, socket |> assign(:agent, assigns.agent) |> assign(:sys_info, AsyncResult.loading())} # |> start_async(:get_sys_info, fn -> # Prymn.Agents.get_sys_info(assigns.agent) # end)} end @impl true def render(assigns) do ~H"""
<.async_result :let={sys_info} assign={@sys_info}> <:loading>
<.spinner size="sm" />

Loading system statistics...

<%= sys_info.uptime || "" %>s

Uptime

<%= Enum.count(sys_info.cpus || []) %>

CPUs

<%= calculate_cpu_usage(sys_info.cpus) %>

CPU%

<%= bytes_to_gigabytes(sys_info.mem_total_bytes - sys_info.mem_avail_bytes) %> / <%= bytes_to_gigabytes(sys_info.mem_total_bytes) %> GiB

Memory

<%= calculate_disk_used_percent(sys_info.disks) %> %

Used Disk

""" end # @impl true # def handle_async(:get_sys_info, {:ok, %SysInfoResponse{} = sys_info}, socket) do # %{sys_info: sys_info_result, agent: agent} = socket.assigns # {:noreply, # socket # |> assign(:sys_info, AsyncResult.ok(sys_info_result, sys_info)) # |> start_async(:get_sys_info, fn -> # # 10 seconds is >5 which is gun's timeout duration (which might have a race # # condition if they are equal) # Process.sleep(:timer.seconds(10)) # Prymn.Agents.get_sys_info(agent) # end)} # end # def handle_async(:get_sys_info, {:ok, {:error, grpc_error}}, socket) do # %{sys_info: sys_info_result} = socket.assigns # {:noreply, # socket # |> assign(:sys_info, AsyncResult.failed(sys_info_result, grpc_error))} # end # def handle_async(:get_sys_info, {:exit, _reason}, socket) do # {:noreply, socket} # end defp calculate_cpu_usage(cpus) do (Enum.reduce(cpus, 0, fn x, acc -> x.usage + acc end) / Enum.count(cpus)) |> Float.round(2) end defp bytes_to_gigabytes(bytes) do Float.round(bytes / Integer.pow(1024, 3), 2) end defp calculate_disk_used_percent(disks) do 0 # 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 end