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:
parent
0e17984d6f
commit
03e46f81f8
12 changed files with 57 additions and 36 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
4
mix.exs
4
mix.exs
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue