mirror of
https://github.com/benbusby/farside.git
synced 2025-08-17 11:00:23 -04:00

Although the current list of queries is only 2 elements ("time" and "weather"), this allows searches for Whoogle and Searx to be slightly more random, and potentially avoid any issues with their parent engine rate limiting them.
102 lines
2.6 KiB
Elixir
102 lines
2.6 KiB
Elixir
defmodule Farside.Instances do
|
|
@fallback_suffix Application.fetch_env!(:farside, :fallback_suffix)
|
|
@update_file Application.fetch_env!(:farside, :update_file)
|
|
@services_json Application.fetch_env!(:farside, :services_json)
|
|
@service_prefix Application.fetch_env!(:farside, :service_prefix)
|
|
@headers Application.fetch_env!(:farside, :headers)
|
|
@queries Application.fetch_env!(:farside, :queries)
|
|
|
|
def sync() do
|
|
File.rename(@update_file, "#{@update_file}-prev")
|
|
update()
|
|
|
|
# Add UTC time of last update
|
|
Redix.command(:redix, [
|
|
"SET",
|
|
"last_updated",
|
|
Calendar.strftime(DateTime.utc_now(), "%c")
|
|
])
|
|
end
|
|
|
|
def request(url) do
|
|
cond do
|
|
System.get_env("FARSIDE_TEST") ->
|
|
:good
|
|
|
|
true ->
|
|
case HTTPoison.get(url, @headers) do
|
|
{:ok, %HTTPoison.Response{status_code: 200}} ->
|
|
# TODO: Add validation of results, not just status code
|
|
:good
|
|
|
|
_ ->
|
|
:bad
|
|
end
|
|
end
|
|
end
|
|
|
|
def update() do
|
|
{:ok, file} = File.read(@services_json)
|
|
{:ok, json} = Poison.decode(file, as: [%Service{}])
|
|
|
|
# Loop through all instances and check each for availability
|
|
for service <- json do
|
|
IO.puts("======== " <> service.type)
|
|
|
|
result =
|
|
Enum.filter(service.instances, fn instance_url ->
|
|
request_url = instance_url <>
|
|
EEx.eval_string(
|
|
service.test_url,
|
|
query: Enum.random(@queries)
|
|
)
|
|
|
|
IO.puts(" " <> request_url)
|
|
|
|
request(request_url) == :good
|
|
end)
|
|
|
|
add_to_redis(service, result)
|
|
log_results(service.type, result)
|
|
end
|
|
end
|
|
|
|
def add_to_redis(service, instances) do
|
|
# Remove previous list of instances
|
|
Redix.command(:redix, [
|
|
"DEL",
|
|
"#{@service_prefix}#{service.type}"
|
|
])
|
|
|
|
# Update with new list of available instances
|
|
Redix.command(
|
|
:redix,
|
|
[
|
|
"LPUSH",
|
|
"#{@service_prefix}#{service.type}"
|
|
] ++ instances
|
|
)
|
|
|
|
# Set fallback to one of the available instances,
|
|
# or the default instance if all are "down"
|
|
if Enum.count(instances) > 0 do
|
|
Redix.command(:redix, [
|
|
"SET",
|
|
"#{service.type}#{@fallback_suffix}",
|
|
Enum.random(instances)
|
|
])
|
|
else
|
|
Redix.command(:redix, [
|
|
"SET",
|
|
"#{service.type}#{@fallback_suffix}",
|
|
service.fallback
|
|
])
|
|
end
|
|
end
|
|
|
|
def log_results(service_name, results) do
|
|
{:ok, file} = File.open(@update_file, [:append, {:delayed_write, 100, 20}])
|
|
IO.write(file, "#{service_name}: #{inspect(results)}\n")
|
|
File.close(file)
|
|
end
|
|
end
|