A simple mix task scheduler for Elixir apps
defmodule MyApp.Scheduler do
@moduledoc """
Schedules a Mix task to be run at a given interval in milliseconds.
## Options
- `:task`: The name of the Mix task to run.
- `:args`: A list of arguments to pass to the Mix task's `run/1` function.
- `:interval`: The time interval in millisconds to rerun the task.
## Example
In a supervisor:
worker(MyApp.Scheduler, [[[
task: "contest.pick_winners",
args: [],
interval: 60000
]]], id: :contest_winners)
On its own:
MyApp.Scheduler.start_link([task: "ping", args: [], interval: 3000])
"""
use GenServer
require Logger
def start_link(opts) do
{:ok, pid} = GenServer.start_link(__MODULE__, opts)
:timer.apply_interval(opts[:interval], __MODULE__, :perform, [pid])
{:ok, pid}
end
def perform(scheduler) do
GenServer.cast(scheduler, :perform)
end
def handle_cast(:perform, opts) do
Logger.info(~s{Scheduler running "mix #{opts[:task]}" with args #{inspect(opts[:args])}})
Mix.Task.run(opts[:task], opts[:args])
Mix.Task.reenable(opts[:task])
{:noreply, opts}
end
end