-
-
Save viktor-evdokimov/4b7483058c0d14b9f28375f3be70c342 to your computer and use it in GitHub Desktop.
A simple mix task scheduler for Elixir apps
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment