chronoscope/lib/chronoscope/gemini/client.ex

75 lines
1.6 KiB
Elixir

defmodule Chronoscope.Gemini.Client do
use GenServer, restart: :transient
alias Chronoscope.Gemini
alias Chronoscope.Gemini.ConnectionClient
@interval_in_seconds 30
@date_time Application.compile_env(:chronoscope, :date_time, DateTime)
def start_link(resource: resource, name: name) do
GenServer.start_link(__MODULE__, resource, name: name)
end
@impl true
def init(resource) do
now = utc_now()
{:ok,
%{
resource: resource,
response: {:error, "initializing"},
last_request: DateTime.add(now, -@interval_in_seconds, :second)
}}
end
@impl true
def handle_call(:terminate, _from, state) do
{:stop, :normal, self(), state}
end
@impl true
def handle_call(:list, _from, state) do
{:reply, state, state}
end
@impl true
def handle_call(:connect, _from, state) do
new_state = update_state(state)
{:reply, new_state.response, new_state}
end
defp update_state(state) do
now = utc_now()
if interval_surpassed?(now, state.last_request) do
Map.merge(state, current_data(state, now))
else
state
end
end
defp current_data(state, now) do
%{
response: server_response(state),
last_request: now
}
end
defp server_response(%{resource: resource}) do
Gemini.TaskSupervisor
|> Task.Supervisor.async(fn -> ConnectionClient.connect(resource) end)
|> Task.await()
end
defp interval_surpassed?(now, last_request) do
DateTime.diff(now, last_request, :second) >= @interval_in_seconds
end
defp utc_now() do
@date_time.utc_now()
end
end