summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/farside/application.ex10
-rw-r--r--lib/farside/instances.ex86
-rw-r--r--lib/farside/scheduler.ex3
-rw-r--r--lib/farside/server.ex22
4 files changed, 117 insertions, 4 deletions
diff --git a/lib/farside/application.ex b/lib/farside/application.ex
index d1c5e25..7427e89 100644
--- a/lib/farside/application.ex
+++ b/lib/farside/application.ex
@@ -7,7 +7,8 @@ defmodule Farside.Application do
@impl true
def start(_type, _args) do
- plug_children = [
+
+ plug_children = System.get_env("FARSIDE_NO_ROUTER") && [] || [
Plug.Cowboy.child_spec(
scheme: :http,
plug: Farside.Router,
@@ -19,9 +20,10 @@ defmodule Farside.Application do
]
children = [
- {Redix, {@redis_conn, [name: :redix]}} |
- System.get_env("FARSIDE_NO_ROUTER") && [] || plug_children
- ]
+ {Redix, {@redis_conn, [name: :redix]}},
+ Farside.Scheduler,
+ Farside.Server
+ ] ++ plug_children
opts = [strategy: :one_for_one, name: Farside.Supervisor]
Supervisor.start_link(children, opts)
diff --git a/lib/farside/instances.ex b/lib/farside/instances.ex
new file mode 100644
index 0000000..203ddfa
--- /dev/null
+++ b/lib/farside/instances.ex
@@ -0,0 +1,86 @@
+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)
+
+ 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) 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) ->
+ IO.puts " " <> 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_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
diff --git a/lib/farside/scheduler.ex b/lib/farside/scheduler.ex
new file mode 100644
index 0000000..4707624
--- /dev/null
+++ b/lib/farside/scheduler.ex
@@ -0,0 +1,3 @@
+defmodule Farside.Scheduler do
+ use Quantum, otp_app: :farside
+end
diff --git a/lib/farside/server.ex b/lib/farside/server.ex
new file mode 100644
index 0000000..1d5bb76
--- /dev/null
+++ b/lib/farside/server.ex
@@ -0,0 +1,22 @@
+defmodule Farside.Server do
+ use GenServer
+ import Crontab.CronExpression
+
+ def init(init_arg) do
+ {:ok, init_arg}
+ end
+
+ def start_link(arg) do
+ if System.get_env("FARSIDE_TEST") do
+ IO.puts("Skipping sync job setup...")
+ else
+ Farside.Scheduler.new_job()
+ |> Quantum.Job.set_name(:sync)
+ |> Quantum.Job.set_schedule(~e[*/5 * * * *])
+ |> Quantum.Job.set_task(fn -> Farside.Instances.sync end)
+ |> Farside.Scheduler.add_job()
+ end
+
+ GenServer.start_link(__MODULE__, arg)
+ end
+end