2023-08-25 21:51:04 +00:00
|
|
|
defmodule Prymn.Agents.Health do
|
2023-08-28 20:32:42 +00:00
|
|
|
@moduledoc """
|
|
|
|
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.
|
2023-08-25 21:51:04 +00:00
|
|
|
"""
|
|
|
|
|
2023-08-28 20:32:42 +00:00
|
|
|
defstruct [:host, :version, message: "Unknown"]
|
2023-08-25 21:51:04 +00:00
|
|
|
|
|
|
|
alias PrymnProto.Prymn.HealthResponse
|
|
|
|
|
|
|
|
@type t :: %{
|
2023-08-28 20:32:42 +00:00
|
|
|
host: String.t(),
|
2023-08-25 21:51:04 +00:00
|
|
|
version: String.t(),
|
|
|
|
message: String.t()
|
|
|
|
}
|
|
|
|
|
|
|
|
def start() do
|
|
|
|
:ets.new(__MODULE__, [:set, :public, :named_table, read_concurrency: true])
|
|
|
|
end
|
|
|
|
|
2023-08-28 20:32:42 +00:00
|
|
|
def subscribe(host) do
|
|
|
|
Phoenix.PubSub.subscribe(Prymn.PubSub, "health:#{host}")
|
2023-08-25 21:51:04 +00:00
|
|
|
end
|
|
|
|
|
2023-08-28 20:32:42 +00:00
|
|
|
def broadcast!(%__MODULE__{host: host} = health) do
|
|
|
|
Phoenix.PubSub.broadcast!(Prymn.PubSub, "health:#{host}", health)
|
2023-08-25 21:51:04 +00:00
|
|
|
end
|
|
|
|
|
2023-08-28 20:32:42 +00:00
|
|
|
def update_and_broadcast(nil) do
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
|
|
|
def update_and_broadcast(%__MODULE__{host: host} = health) do
|
|
|
|
:ets.insert(__MODULE__, {host, health})
|
|
|
|
broadcast!(health)
|
|
|
|
end
|
|
|
|
|
|
|
|
def delete(host_address) do
|
|
|
|
:ets.delete(__MODULE__, host_address)
|
|
|
|
end
|
|
|
|
|
|
|
|
def lookup(host_address, opts \\ []) do
|
|
|
|
default = Keyword.get(opts, :default, false)
|
|
|
|
|
2023-08-25 21:51:04 +00:00
|
|
|
case :ets.lookup(__MODULE__, host_address) do
|
|
|
|
[{^host_address, value}] -> value
|
2023-08-28 20:32:42 +00:00
|
|
|
[] when default -> %__MODULE__{host: host_address}
|
2023-08-25 21:51:04 +00:00
|
|
|
[] -> nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-08-28 20:32:42 +00:00
|
|
|
def make_timed_out(%__MODULE__{} = health) do
|
|
|
|
%__MODULE__{health | message: "Connect timed out"}
|
|
|
|
end
|
2023-08-25 21:51:04 +00:00
|
|
|
|
2023-08-28 20:32:42 +00:00
|
|
|
def make_disconnected(%__MODULE__{} = health) do
|
|
|
|
%__MODULE__{health | message: "Disconnected"}
|
|
|
|
end
|
2023-08-25 21:51:04 +00:00
|
|
|
|
2023-08-28 20:32:42 +00:00
|
|
|
def make_from_proto(%HealthResponse{system: system, version: version, tasks: tasks}, host) do
|
|
|
|
%__MODULE__{host: host}
|
|
|
|
|> do_version(version)
|
|
|
|
|> do_system(system)
|
|
|
|
|> do_tasks(tasks)
|
2023-08-25 21:51:04 +00:00
|
|
|
end
|
|
|
|
|
2023-08-28 20:32:42 +00:00
|
|
|
defp do_version(health, version) do
|
|
|
|
%__MODULE__{health | version: version}
|
|
|
|
end
|
2023-08-25 21:51:04 +00:00
|
|
|
|
2023-08-28 20:32:42 +00:00
|
|
|
defp do_system(health, system) do
|
|
|
|
case system.status do
|
|
|
|
"normal" -> %__MODULE__{health | message: "Connected"}
|
|
|
|
status -> %__MODULE__{health | message: "Alert: #{status}"}
|
2023-08-25 21:51:04 +00:00
|
|
|
end
|
|
|
|
end
|
2023-08-28 20:32:42 +00:00
|
|
|
|
|
|
|
defp do_tasks(health, _tasks) do
|
|
|
|
health
|
|
|
|
end
|
2023-08-25 21:51:04 +00:00
|
|
|
end
|