61 lines
1.6 KiB
Elixir
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
|