chronoscope/lib/chronoscope/nts/client.ex
2024-03-27 09:19:21 -04:00

81 lines
1.8 KiB
Elixir

defmodule Chronoscope.NTS.Client do
use GenServer
alias Chronoscope.NTS.KeyEstablishmentClient
@interval_in_seconds 30
def start_link(_) do
GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
end
@impl true
def init(_) do
{:ok, %{}}
end
@impl true
def handle_call(:healthy?, _from, state) do
{:reply, true, state}
end
@impl true
def handle_call(:list, _from, state) do
{:reply, state, state}
end
@impl true
def handle_call({:key_establishment, server}, _from, state) do
new_state = update_state(server, state)
{:reply, get_response(server, new_state), new_state}
end
defp update_state(server, state) do
now = DateTime.utc_now()
last_key_establishment = get_last_key_establishment(server, state, now)
if interval_surpassed?(now, last_key_establishment) do
Map.put(state, server, current_data(server, now))
else
state
end
end
defp get_response(server, state) do
state
|> Map.get(server)
|> Map.get(:key_establishment_response)
end
defp get_last_key_establishment(server, state, now) do
state
|> Map.get(server, initial_data(now))
|> Map.get(:last_key_establishment)
end
defp initial_data(now) do
%{
response: {:error, "uninitialized"},
last_key_establishment: DateTime.add(now, -@interval_in_seconds, :second)
}
end
defp current_data(server, now) do
# fixme - handle each request asynchronously
response =
Chronoscope.TaskSupervisor
|> Task.Supervisor.async(fn -> KeyEstablishmentClient.key_establishment(server) end)
|> Task.await(10_000)
%{
key_establishment_response: response,
last_key_establishment: now
}
end
defp interval_surpassed?(now, last_key_establishment) do
DateTime.diff(now, last_key_establishment, :second) >= @interval_in_seconds
end
end