1
0
Fork 0
mirror of https://github.com/benbusby/farside.git synced 2025-06-08 02:16:36 +00:00
farside/lib/farside/server.ex
2022-07-28 02:35:57 -07:00

107 lines
2.1 KiB
Elixir

defmodule Farside.Instance.Server do
use GenServer
require Logger
@registry_name :servers
def child_spec(args) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [args]},
type: :worker
}
end
def init(init_arg) do
ref =
:ets.new(String.to_atom(init_arg.type), [
:set,
:named_table,
:public,
read_concurrency: true,
write_concurrency: true
])
:ets.insert(ref, {:data, init_arg})
{:ok, %{type: init_arg.type, ref: ref}}
end
def start_link(arg) do
name = via_tuple(arg.type)
GenServer.start_link(__MODULE__, arg, name: name)
end
def shutdown() do
GenServer.call(__MODULE__, :shutdown)
end
def handle_call(
:shutdown,
_from,
state
) do
{:stop, {:ok, "Normal Shutdown"}, state}
end
def handle_cast(
:shutdown,
state
) do
{:stop, :normal, state}
end
def handle_cast(
:update,
state
) do
service = :ets.lookup(String.to_atom(state.type), :data)
{_, service} = List.first(service)
queries = Application.fetch_env!(:farside, :queries)
instances =
Enum.filter(service.instances, fn instance_url ->
request_url =
instance_url <>
EEx.eval_string(
service.test_url,
query: Enum.random(queries)
)
Logger.info("Testing: #{request_url}")
Farside.Http.request(request_url) == :good
end)
values = %{service | instances: instances}
:ets.delete_all_objects(String.to_atom(state.type))
:ets.insert(state.ref, {:data, values})
update_file = Application.fetch_env!(:farside, :update_file)
File.write(update_file, values.fallback)
{:noreply, state}
end
@doc false
def via_tuple(data, registry \\ @registry_name) do
{:via, Registry, {registry, data}}
end
@impl true
def handle_info({:DOWN, ref, :process, _pid, _reason}, {names, refs}) do
:ets.delete(names)
{:noreply, {names, refs}}
end
@impl true
def handle_info(_msg, state) do
{:noreply, state}
end
end