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