Skip to content

Instantly share code, notes, and snippets.

@danielberkompas
Created October 26, 2016 17:59
Show Gist options
  • Save danielberkompas/7212ef0ba261e4a19a0b86ec1e109282 to your computer and use it in GitHub Desktop.
Save danielberkompas/7212ef0ba261e4a19a0b86ec1e109282 to your computer and use it in GitHub Desktop.

Revisions

  1. danielberkompas created this gist Oct 26, 2016.
    46 changes: 46 additions & 0 deletions scheduler.ex
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,46 @@
    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