farside/update.exs
Ben Busby 4949ae22bb
Output available instances and fallback URL to redis
Once a list of available URLs has been determined for a particular
service, the list is written as "service -> [list of instances]" to a
local redis connection. These can then be used in the greater routing
logic to pick a random instance from the list, or use a fallback
instance if none are determined to be available.
2021-10-22 17:15:40 -06:00

71 lines
1.5 KiB
Elixir

defmodule Service do
defstruct [
type: nil,
test_url: nil,
fallback: nil,
instances: []
]
end
defmodule Instances do
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, conn} = Redix.start_link(
"redis://localhost:6379",
name: :redix
)
{: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(conn, service, result)
end
end
def add_to_redis(conn, service, instances) do
# Remove previous list of instances
Redix.command(conn, [
"DEL",
service.type
])
# Update with new list of available instances
Redix.command(conn, [
"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(conn, [
"SET",
service.type <> "-fallback",
Enum.random(instances)
])
else
Redix.command(conn, [
"SET",
service.type <> "-fallback",
service.fallback
])
end
end
end
Instances.update("services.json")