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.
66 lines
1.7 KiB
Elixir
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
|