1
0
Fork 0
mirror of https://github.com/benbusby/farside.git synced 2025-06-08 02:16:36 +00:00

add error handling

This commit is contained in:
mithereal 2022-09-17 03:38:06 -07:00
parent 0e17984d6f
commit 03e46f81f8
12 changed files with 57 additions and 36 deletions

View file

@ -110,11 +110,12 @@ defmodule Farside do
end end
|> Enum.reject(fn x -> x == nil end) |> Enum.reject(fn x -> x == nil end)
service = Map.put( service =
service, Map.put(
:instances, service,
instances :instances,
) instances
)
case Enum.count(service.instances) > 0 do case Enum.count(service.instances) > 0 do
true -> Enum.random(service.instances) true -> Enum.random(service.instances)

View file

@ -23,7 +23,7 @@ defmodule Farside.Application do
maybe_loaded_children = maybe_loaded_children =
case is_nil(System.get_env("FARSIDE_TEST")) do case is_nil(System.get_env("FARSIDE_TEST")) do
true -> true ->
[{HealthyCheck, []},{UnHealthyCheck, []},{DeadCheck, []}] [{HealthyCheck, []}, {UnHealthyCheck, []}, {DeadCheck, []}]
false -> false ->
Logger.info("Skipping sync job setup...") Logger.info("Skipping sync job setup...")
@ -45,7 +45,7 @@ defmodule Farside.Application do
{DynamicSupervisor, strategy: :one_for_one, name: :service_supervisor}, {DynamicSupervisor, strategy: :one_for_one, name: :service_supervisor},
{Registry, keys: :unique, name: :instance}, {Registry, keys: :unique, name: :instance},
{Registry, keys: :unique, name: :service}, {Registry, keys: :unique, name: :service},
{Registry, keys: :duplicate, name: :status, partitions: System.schedulers_online()}, {Registry, keys: :duplicate, name: :status, partitions: System.schedulers_online()}
] ++ maybe_loaded_children ] ++ maybe_loaded_children
opts = [strategy: :one_for_one, name: Farside.Supervisor] opts = [strategy: :one_for_one, name: Farside.Supervisor]
@ -81,8 +81,6 @@ defmodule Farside.Application do
|> HealthyCheck.load() |> HealthyCheck.load()
end end
LastUpdated.value(DateTime.utc_now())
response response
end end
end end

View file

@ -3,6 +3,7 @@ defmodule Farside.Server.DeadCheck do
Module to check/validate the instance list only for servers with empty instance list every 90 secs, if a sync/check process isnt already running Module to check/validate the instance list only for servers with empty instance list every 90 secs, if a sync/check process isnt already running
""" """
use Task use Task
alias Farside.LastUpdated
def child_spec(args) do def child_spec(args) do
%{ %{
@ -26,6 +27,8 @@ defmodule Farside.Server.DeadCheck do
end end
def run() do def run() do
LastUpdated.value(DateTime.utc_now())
Registry.dispatch(:status, "dead", fn entries -> Registry.dispatch(:status, "dead", fn entries ->
for {pid, _} <- entries, do: GenServer.cast(pid, :check) for {pid, _} <- entries, do: GenServer.cast(pid, :check)
end) end)

View file

@ -3,6 +3,7 @@ defmodule Farside.Server.HealthyCheck do
Module to validate healthy servers Module to validate healthy servers
""" """
use Task use Task
alias Farside.LastUpdated
def child_spec(args) do def child_spec(args) do
%{ %{
@ -31,10 +32,13 @@ defmodule Farside.Server.HealthyCheck do
GenServer.cast(pid, :check) GenServer.cast(pid, :check)
end end
end) end)
params params
end end
def run() do def run() do
LastUpdated.value(DateTime.utc_now())
Registry.dispatch(:status, "healthy", fn entries -> Registry.dispatch(:status, "healthy", fn entries ->
for {pid, url} <- entries do for {pid, url} <- entries do
GenServer.cast(pid, :check) GenServer.cast(pid, :check)

View file

@ -27,7 +27,6 @@ defmodule Farside.Http do
end end
def request(url, type) do def request(url, type) do
cond do cond do
System.get_env("FARSIDE_TEST") -> System.get_env("FARSIDE_TEST") ->
:good :good
@ -41,6 +40,10 @@ defmodule Farside.Http do
Logger.info("Type: #{type}, Response: [#{n}], Url: #{url}") Logger.info("Type: #{type}, Response: [#{n}], Url: #{url}")
:good :good
nil ->
Logger.error("Type: #{type}, Response: [408], Url: #{url}")
:bad
n -> n ->
Logger.error("Type: #{type}, Response: [#{n}], Url: #{url}") Logger.error("Type: #{type}, Response: [#{n}], Url: #{url}")
:bad :bad
@ -82,7 +85,8 @@ defmodule Farside.Http do
end end
def test_service(service) do def test_service(service) do
url = service.url <> service.test_url url = service.url <> service.test_url
test_url = test_url =
EEx.eval_string( EEx.eval_string(
url, url,
@ -107,7 +111,7 @@ url = service.url <> service.test_url
unless is_nil(data) do unless is_nil(data) do
{_test_url, value, _service} = data {_test_url, value, _service} = data
value value
else else
:bad :bad
end end
end end

View file

@ -55,7 +55,6 @@ defmodule Farside.Instance do
{:stop, :normal, state} {:stop, :normal, state}
end end
@doc false @doc false
def via_tuple(id, registry \\ @registry_name) do def via_tuple(id, registry \\ @registry_name) do
{:via, Registry, {registry, id}} {:via, Registry, {registry, id}}
@ -67,12 +66,12 @@ defmodule Farside.Instance do
{:noreply, {names, refs}} {:noreply, {names, refs}}
end end
@impl true @impl true
def handle_info(:load, state) do def handle_info(:load, state) do
service = :ets.lookup(String.to_atom(state.type), :default) service = :ets.lookup(String.to_atom(state.type), :default)
{_, service} = List.first(service) {_, service} = List.first(service)
service.instances service.instances
|> Enum.each(fn url -> |> Enum.each(fn url ->
initial_state = %{url: url, type: service.type, test_url: service.test_url} initial_state = %{url: url, type: service.type, test_url: service.test_url}

View file

@ -31,11 +31,11 @@ defmodule Farside.Instance.Supervisor do
def start(opts \\ %{}) do def start(opts \\ %{}) do
child_spec = {SERVER, opts} child_spec = {SERVER, opts}
{:ok,pid} = DynamicSupervisor.start_child(@name, child_spec) {:ok, pid} = DynamicSupervisor.start_child(@name, child_spec)
send(pid, :load) send(pid, :load)
{:ok,pid} {:ok, pid}
end end
def stop(id) do def stop(id) do

View file

@ -91,11 +91,18 @@ defmodule Farside.Service do
@impl true @impl true
def handle_cast(:check, state) do def handle_cast(:check, state) do
reply = Http.test_service(state) reply = Http.test_service(state)
status = state.status ++ [reply] status = state.status ++ [reply]
max_queue = Application.get_env(:farside, :max_fail_rate, 50) + 5
status =
case Enum.count(status) < max_queue do
true -> status
false -> []
end
state = %{state | status: status} state = %{state | status: status}
state = %{state | last_update: DateTime.utc_now()} state = %{state | last_update: DateTime.utc_now()}
@ -112,24 +119,28 @@ defmodule Farside.Service do
Registry.unregister_match(:status, unhealthy, state.url) Registry.unregister_match(:status, unhealthy, state.url)
Registry.unregister_match(:status, dead, state.url) Registry.unregister_match(:status, dead, state.url)
if reply != :good do state =
filtered = Enum.reject(status, fn x -> x == :good end) if reply != :good do
filtered = Enum.reject(status, fn x -> x == :good end)
fails_before_death = Application.get_env(:farside, :max_fail_rate, 50) fails_before_death = Application.get_env(:farside, :max_fail_rate, 50)
case Enum.count(filtered) < fails_before_death do case Enum.count(filtered) < fails_before_death do
true -> true ->
Registry.register(:status, "unhealthy", state.url) Registry.register(:status, "unhealthy", state.url)
Registry.register(:status, unhealthy, state.url) Registry.register(:status, unhealthy, state.url)
state
false -> false ->
Registry.register(:status, "dead", state.url) Registry.register(:status, "dead", state.url)
Registry.register(:status, dead, state.url) Registry.register(:status, dead, state.url)
%{state | status: [:bad]}
end
else
Registry.register(:status, "healthy", state.url)
Registry.register(:status, healthy, state.url)
state
end end
else
Registry.register(:status, "healthy", state.url)
Registry.register(:status, healthy, state.url)
end
{:noreply, state} {:noreply, state}
end end

View file

@ -3,6 +3,7 @@ defmodule Farside.Server.UnHealthyCheck do
Module to check/validate the instance list only for servers with empty instance list every 90 secs, if a sync/check process isnt already running Module to check/validate the instance list only for servers with empty instance list every 90 secs, if a sync/check process isnt already running
""" """
use Task use Task
alias Farside.LastUpdated
def child_spec(args) do def child_spec(args) do
%{ %{
@ -26,6 +27,8 @@ defmodule Farside.Server.UnHealthyCheck do
end end
def run() do def run() do
LastUpdated.value(DateTime.utc_now())
Registry.dispatch(:status, "unhealthy", fn entries -> Registry.dispatch(:status, "unhealthy", fn entries ->
for {pid, _} <- entries, do: GenServer.cast(pid, :check) for {pid, _} <- entries, do: GenServer.cast(pid, :check)
end) end)

View file

@ -31,8 +31,7 @@ defmodule Farside.MixProject do
end end
defp aliases do defp aliases do
[ []
]
end end
# Run "mix help deps" to learn about dependencies. # Run "mix help deps" to learn about dependencies.
@ -46,7 +45,6 @@ defmodule Farside.MixProject do
] ]
end end
defp description() do defp description() do
"A redirecting service for FOSS alternative frontends." "A redirecting service for FOSS alternative frontends."
end end