dotfiles/app/lib/prymn/agents/health.ex
Nikos Papadakis be7f584010
app: a nice poc background connection with the agent
Dynamically supervise a GRPC connection and keep it alive for a while,
using a timeout to kill the process on inactivity.

The Connection GenServer keeps the connection alive, while listening to
a health stream from the GRPC endpoint, notifying any subscribed
listeners about changes to health.

This health is then propagated to the main servers page.

Also create a looping get_sys_info which retrieves some basic system
information.
2023-08-26 00:51:04 +03:00

66 lines
1.7 KiB
Elixir

defmodule Prymn.Agents.Health do
@doc """
The Health struct keeps simple health information of
whether or not the target host machine is up to date, has any tasks running,
its resources are getting depleted, or if it's unable be reached.
"""
defstruct [:version, message: "Unknown"]
alias PrymnProto.Prymn.HealthResponse
@type t :: %{
version: String.t(),
message: String.t()
}
@doc false
def start() do
:ets.new(__MODULE__, [:set, :public, :named_table, read_concurrency: true])
end
@doc false
def subscribe(host_address) do
Phoenix.PubSub.subscribe(Prymn.PubSub, "health:#{host_address}")
end
@doc false
def update(health, host_address) do
:ets.insert(__MODULE__, {host_address, health})
Phoenix.PubSub.broadcast!(Prymn.PubSub, "health:#{host_address}", {host_address, health})
end
@doc false
def lookup(host_address) do
case :ets.lookup(__MODULE__, host_address) do
[{^host_address, value}] -> value
[] -> nil
end
end
@doc false
def new_from_proto(proto_health) do
case proto_health do
%HealthResponse{} = health ->
from_health(health)
%GRPC.RPCError{message: ":stream_error: :closed"} ->
%__MODULE__{message: "Disconnected"}
%GRPC.RPCError{} = error ->
require Logger
Logger.error("unhandled GRPC error received in Health module: #{inspect(error)}")
%__MODULE__{message: "Error retrieving server status"}
end
end
defp from_health(%HealthResponse{system: system, version: version}) do
case system.status do
"normal" ->
%__MODULE__{message: "Connected", version: version}
status ->
%__MODULE__{message: status, version: version}
end
end
end