chronoscope/lib/chronoscope/nts.ex

62 lines
1.6 KiB
Elixir

defmodule Chronoscope.NTS.Behaviour do
@callback(key_establishment(host :: String.t(), port :: integer()) :: {:ok, Map.t()}, {:error, any()})
end
# TODO - create macro
defmodule Chronoscope.NTS do
@behaviour Chronoscope.NTS.Behaviour
require Logger
alias Chronoscope.NTS
@registry Application.compile_env(:chronoscope, :registry, Registry)
@genserver Application.compile_env(:chronoscope, :gen_server, GenServer)
@dynamic_supervisor Application.compile_env(:chronoscope, :dynamic_supervisor, DynamicSupervisor)
def healthy?() do
true
end
def list() do
NTS.DynamicSupervisor
|> @dynamic_supervisor.which_children()
|> Enum.map(fn {_, pid, _, _} -> @genserver.call(pid, :list) end)
end
def remove(host, port) do
name = client_name(%{host: host, port: port})
case @registry.lookup(NTS.Registry, name) do
[{pid, _}] -> {:ok, @genserver.call(pid, :terminate)}
[] -> {:error, :not_found}
end
end
@impl true
def key_establishment(host, port) do
%{host: host, port: port}
|> client_pid()
|> @genserver.call(:key_establishment)
end
defp client_pid(server) do
name = client_name(server)
case @registry.lookup(NTS.Registry, name) do
[{pid, _}] -> pid
[] -> start_client(server, name)
end
end
defp client_name(%{host: host, port: port}) do
"#{host}:#{port}"
end
defp start_client(server, name) do
NTS.DynamicSupervisor
|> @dynamic_supervisor.start_child({NTS.Client, server: server, name: {:via, @registry, {NTS.Registry, name}}})
|> then(fn {:ok, pid} -> pid end)
end
end