mirror of
https://github.com/benbusby/farside.git
synced 2025-04-29 23:20:03 +00:00
Use quantum core for update scheduling
Rather than requiring a traditional crontab install, the app now leverages quantum-core (link below) to schedule the instance update/sync task every 5 minutes. Some updates as a result: - The new job is scheduled at runtime in server.ex. - The update.exs script was refactored to be compiled along with the rest of the app as instances.ex. - Scheduler and Server modules were added for creating and executing the new update task - All shell scripts were removed, as they are no longer needed https://github.com/quantum-elixir/quantum-core
This commit is contained in:
parent
d1c9212994
commit
ff97d258f0
10 changed files with 53 additions and 36 deletions
|
@ -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)
|
||||
|
|
86
lib/farside/instances.ex
Normal file
86
lib/farside/instances.ex
Normal file
|
@ -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
|
3
lib/farside/scheduler.ex
Normal file
3
lib/farside/scheduler.ex
Normal file
|
@ -0,0 +1,3 @@
|
|||
defmodule Farside.Scheduler do
|
||||
use Quantum, otp_app: :farside
|
||||
end
|
22
lib/farside/server.ex
Normal file
22
lib/farside/server.ex
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue