A Simple Scheduled Task in Phoenix

I have been writing an online version of Timeline, a game where you try to correctly place historical events on a timeline. I am using PhoenixFramework along with Ember.js on the front end (you can see the full code here). Today I will discuss one small part of the Phoenix side: how to run scheduled jobs.

The use case is that after a certain threshold, I want to delete completed and inactive games. So we will schedule a task to run at periodic intervals and do this.

The Quantum Package

To schedule jobs, we will use the Quantum Elixir package. When you add it, it becomes just another application in the wonderfully partitioned Elixir mix project structure which Phoenix takes advantage of.

You add Quantum to your Phoenix projects in the mix.exs file as follows:

#mix.exs
def application do
[mod: {YourPhoenixApp, []},
applications: [
...
:quantum
]
]
end
....
defp deps do
[
...
{:quantum, ">= 1.7.1"} #substitute latest version
]
end

Scheduling a Task

To schedule a task, we add an entry to the config. Since we probably want different schedules for development and production, let’s add them to config/dev.exs and config/prod.exs. For development, we’ll run the task every minute, which will look like this:

#config/dev.exs
config :quantum, cron: [
# Every minute
"* * * * *": {Mix.Tasks.PhoenixTimeline.CullOldGames, :cull }
]

Next, let’s write a placeholder task, which we’ll put under lib/mix/tasks:

#lib/mix/tasks/cull_old_games.ex
defmodule Mix.Tasks.PhoenixTimeline.CullOldGames do
@shortdoc "Culls old games"

def cull do
IO.puts "cull task ran"
end
end

If we run iex -S mix (or start the server) and wait a minute, we’ll see that our task gets run. Cool!

That’s it for now. In the next installment, we’ll write the actual code to cull old games. This will involve using config to set cull thresholds and ecto to do the actual deletion. Full code (including a sneak peak ofthose final two tasks) can be found in this commit.