mirror of
https://github.com/benbusby/farside.git
synced 2025-03-15 11:46:32 -04:00

Not sure if this is the Elixir-y way to do this, but seems more logical than hardcoding values such as redis connection. Also went through and improved how string formatting was performed throughout the app. Rather than "combining" <> "strings" this way, I'm now just doing "#${variable}#{formatting}", which looks a lot cleaner.
83 lines
2.0 KiB
Elixir
83 lines
2.0 KiB
Elixir
defmodule Service do
|
|
defstruct [
|
|
type: nil,
|
|
test_url: nil,
|
|
fallback: nil,
|
|
instances: []
|
|
]
|
|
end
|
|
|
|
defmodule Instances do
|
|
@fallback_str Application.fetch_env!(:privacy_revolver, :fallback_str)
|
|
@update_file Application.fetch_env!(:privacy_revolver, :update_file)
|
|
@services_json Application.fetch_env!(:privacy_revolver, :services_json)
|
|
|
|
def init() do
|
|
File.rename(@update_file, "#{@update_file}-prev")
|
|
update(@services_json)
|
|
end
|
|
|
|
def request(url) do
|
|
case HTTPoison.get(url) do
|
|
{:ok, %HTTPoison.Response{status_code: 200}} ->
|
|
# TODO: Add validation of results, not just status code
|
|
:good
|
|
_ ->
|
|
:bad
|
|
end
|
|
end
|
|
|
|
def update(filename) do
|
|
{:ok, file} = File.read(filename)
|
|
{:ok, json} = Poison.decode(file, as: [%Service{}])
|
|
|
|
# Loop through all instances and check each for availability
|
|
for service <- json do
|
|
result = Enum.filter(service.instances, fn(instance_url) ->
|
|
request(instance_url <> service.test_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.type
|
|
])
|
|
|
|
# Update with new list of available instances
|
|
Redix.command(:redix, [
|
|
"LPUSH",
|
|
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_str}",
|
|
Enum.random(instances)
|
|
])
|
|
else
|
|
Redix.command(:redix, [
|
|
"SET",
|
|
"#{service.type}#{@fallback_str}",
|
|
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
|
|
|
|
Instances.init()
|