dotfiles/app/lib/prymn/messaging/connection.ex
2024-02-01 17:34:26 +02:00

64 lines
1.6 KiB
Elixir

defmodule Prymn.Messaging.Connection do
alias Prymn.Agents.Health
use GenServer
defstruct [:conn_pid]
require Logger
@dialyzer {:nowarn_function, init: 1}
@v1_prefix "agents.v1."
def start_link(name) do
GenServer.start_link(__MODULE__, nil, name: name)
end
@impl true
def init(_init_arg) do
connection_properties = %{
host: "localhost",
username: "prymn_admin",
password: "prymn_admin",
name: "Prymn Control",
auth_required: true
}
Process.flag(:trap_exit, true)
case Gnat.start_link(connection_properties) do
{:ok, pid} ->
Logger.info("Connected to NATS")
{:ok, %__MODULE__{conn_pid: pid}, {:continue, :subscribe_to_health}}
{:error, reason} ->
Logger.info("Connection to NATS failed (#{reason}). Attempting reconnect.")
{:ok, nil, {:continue, :attempt_reconnect}}
end
end
@impl true
def handle_continue(:attempt_reconnect, state) do
Process.sleep(3000)
{:stop, {:shutdown, :connection_failure}, state}
end
def handle_continue(:subscribe_to_health, %__MODULE__{} = state) do
{:ok, _subscription} = Gnat.sub(state.conn_pid, self(), @v1_prefix <> "*.health")
{:noreply, state}
end
@impl true
def handle_info({:EXIT, _pid, _reason}, state) do
Logger.info("Lost connection to NATS. Attempting reconnect.")
{:noreply, state, {:continue, :attempt_reconnect}}
end
def handle_info({:msg, %{body: body, topic: @v1_prefix <> topic}}, state) do
[agent_id, "health"] = String.split(topic, ".")
agent_id
|> Health.new(Jason.decode!(body))
|> Health.update_and_broadcast()
{:noreply, state}
end
end