Scheduling a task to run at 8AM UTC time every day

I currently have a task that runs once an hour. This is pretty straightforward using a GenServer. I can call Process.send_after(self(), :work, @interval) in the handle_info/2 function of that module.

If I need to run another task once every day at 8AM UTC, what would be a good way to do this natively (without any external libraries)? Is there something equivalent to Process.send_after except at a specific time?

1 Like

I would calculate the initial_interval to 8AM on init, and then send_after 24 hours every time after that.

5 Likes

You can check Quantum, you can config it like cron:

config :quantum, :your_app,
  cron: [
    # Every minute
    "* * * * *":      {"Heartbeat", :send},
    # Every 15 minutes
    "*/15 * * * *":   fn -> System.cmd("rm", ["/tmp/tmp_"]) end,
    # Runs on 18, 20, 22, 0, 2, 4, 6:
    "0 18-6/2 * * *": fn -> :mnesia.backup('/var/backup/mnesia') end,
    # Runs every midnight:
    "@daily":         &Backup.backup/0
  ]
9 Likes

Speaking of cron, is there some reason this task couldn’t be done through cron? (Or at least triggered by something done through cron?) Sorry if that’s “Just Not Done” in the Elixir world, I’m too new to have a good sense of that – some say I lack good sense at all… %-)

2 Likes

@davearonson, in most cases it’s a better approach to have the scheduling service/system/config as part of your app. It’s easier to deploy and manage that way.

1 Like

I also use quantum in two of my projects. It does amazing job.

1 Like

It is possible to use cron to schedule your jobs. The deployment story is not very good, but if you are up to using ruby, you can use https://github.com/javan/whenever to setup your job and run whenever --update-crontab. One of us should write a whenever runner for distillery.

You can use cron jobs even without using whenever for configuration updates. If you are using Distillery you could put the following in your crontab

0 0 8 1/1 * ? * /opt/www/myapp/bin/app_name rpc Elixir.ScheduledTask run

where our module is

defmodule ScheduledTask def
  def run
    # our code
  end
end
2 Likes

Quantum is fantastic using it in all my applications at the moment, never had any issues

1 Like

One thing to keep in mind when using Process.send_after for something like this is that your app might get restarted in between and that message won’t get send.
You could work around that by scheduling a message again on application startup, though.

4 Likes

Did you have some example not the questum part it self, more like the way how to start that cron, example: for start the web app I run mix phoenix.server how to do that for cron like mix start-cron?

You are looking for mix run

~ $ mix help run 

                                    mix run                                     

Runs the given file or expression in the context of the application.

You can use this task to execute a particular file or command:

    mix run -e Hello.world
    mix run my_script.exs

This task provides a subset of the functionality available in the elixir
executable, including setting up the System.argv/0 arguments:

    mix run my_script.exs arg1 arg2 arg3

You can also use this task to simply start an application and keep it running
without halting:

    mix run --no-halt

Before running any command, the task compiles and starts the current
application. Those can be configured with the options below.

You may also pass options specific to the elixir executable as follows:

    elixir --sname hello -S mix run --no-halt

## Command line options

  • --config, -c  - loads the given configuration file
  • --eval, -e - evaluate the given code
  • --require, -r - requires pattern before running the command
  • --parallel, -p - makes all requires parallel
  • --no-compile - does not compile even if files require compilation
  • --no-deps-check - does not check dependencies
  • --no-archives-check - does not check archives
  • --no-halt - does not halt the system after running the command
  • --no-mixexs - allows the command to run even if there is no mix.exs
  • --no-start - does not start applications after compilation
  • --no-elixir-version-check - does not check the Elixir version from
    mix.exs