chronoscope/lib/chronoscope/gemini.ex

61 lines
1.6 KiB
Elixir

defmodule Chronoscope.Gemini.Behaviour do
@callback(connect(host :: String.t(), port :: integer(), path :: String.t()) :: {:ok, Map.t()}, {:error, any()})
end
defmodule Chronoscope.Gemini do
@behaviour Chronoscope.Gemini.Behaviour
require Logger
alias Chronoscope.Gemini
@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
Gemini.DynamicSupervisor
|> @dynamic_supervisor.which_children()
|> Enum.map(fn {_, pid, _, _} -> @genserver.call(pid, :list) end)
end
def remove(host, port, path) do
name = client_name(%{host: host, port: port, path: path})
case @registry.lookup(Gemini.Registry, name) do
[{pid, _}] -> {:ok, @genserver.call(pid, :terminate)}
[] -> {:error, :not_found}
end
end
@impl true
def connect(host, port, path) do
%{host: host, port: port, path: path}
|> client_pid()
|> @genserver.call(:connect)
end
defp client_pid(resource) do
name = client_name(resource)
case @registry.lookup(Gemini.Registry, name) do
[{pid, _}] -> pid
[] -> start_client(resource, name)
end
end
defp client_name(%{host: host, port: port, path: path}) do
"#{host}:#{port}#{path}"
end
defp start_client(resource, name) do
Gemini.DynamicSupervisor
|> @dynamic_supervisor.start_child({Gemini.Client, resource: resource, name: {:via, @registry, {Gemini.Registry, name}}})
|> then(fn {:ok, pid} -> pid end)
end
end