Skip to main content
Github

Task scheduling

Learn how to create scheduled tasks that can be run crontab-like, repeatedly or just once.

Setup

Before you begin, configure the operating system’s Task scheduling service to execute the required tasks. Examples include cron (configured through crontab) on Unix-like systems, Windows Task Scheduler on Windows, and launchd on macOS.

Enabling in Crontab

You can automatically configure Cron (if the system supports it) using the built-in command:

./run schedule:enable

Disabling in Crontab

./run schedule:disable

Manually configuring cron:

If the automated command is not supported by the environment, it is still possible to manually add a similar instruction to the crontab (adjust the paths):

* * * * * /usr/bin/php /path/to/my-app/run schedule:run >> /path/to/my-app/storage/logs/schedule.log 2>&1

Manually configuring on Windows:

schtasks /Create /TN "Inphinit Schedule" /TR "cmd /c C:\php\php.exe \"C:/path/to/my-app/run\" schedule:run >> \"C:/path/to/my-app/system/storage/logs/schedule.log\" 2>&1" /SC MINUTE /MO 1 /F

Creating tasks

It is possible to schedule functions, existing commands, and shell commands. To schedule a function, edit the system/console.php file and add tasks as in the examples:

use Inphinit\Experimental\Scheduling\Task; $mytask = $scheduler->call('mytask1', function (Task $task) { echo 'Hello World!'; }); // Defines a task to be executed every hour. $mytask->interval(3600);

To schedule an existing command, follow the example:

// Creates the command `php run sample`, which can be executed in the terminal. $mycommand = $console->action('sample', function (Command $command, array $options, array $residues) { echo 'Hello World!'; }); // Schedules the command to be executed according to the next instruction. $mytask = $scheduler->command('mytask2', $mycommand); // Configures the schedule to run at the 10-minute mark. $mytask->interval(600);

It is also possible to schedule arbitrary commands, for example, running VACUUM on Postgres databases at regular intervals:

// Sets the task to run on the 1st of every month at 03:00 AM (UTC). $scheduler->shell('mytask3', 'vacuumdb -d my_database')->cron(0, 3, 1, '*', '*');

Another example using the systemd-tmpfiles program.

// Performs cleanup every day at 23:30 (UTC) $scheduler->shell('mytask4', 'systemd-tmpfiles --clean')->at(23, 30);

Another example using the a NodeJS:

// Performs a JavaScript file using NodeJS every day at 00:00 (UTC) $scheduler->shell('mynodetask', 'node /foo/bar/script.js')->at(0, 0);

Testing a task

To test a task, regardless of the schedule, simply run the command:

./run schedule:run --task mytask1

Configuring the schedule

When adding a task, it is necessary to configure the trigger time and whether execution should occur in the background using the following methods:

Comando Descrição
cron($minute, $hour, $day, $month, $weekday) Schedule the task using crontab-like fields.
interval(int $seconds) Schedule the task to run repeatedly at the specified interval in seconds, counting from its last execution.
once(DateTime $datetime) Schedule the task to run exactly once at (or after) the specified date/time. Once executed, it will not run again.
at(int $hour, int $minute) Shortcut to schedule the task for daily execution at a fixed time. Equivalent to cron($minute, $hour, '*', '*', '*').
runInBackground(bool $enable) Marks this task to be dispatched as an independent background process, rather than running synchronously within the scheduler process.

Since most methods return the instance of the Inphinit\Experimental\Scheduling\Task class itself, it is possible to use them like this:

$scheduler->call('mytask5', function () { ... }) ->cron(30, 16, 1, '*', '*') ->runInBackground(true);

Running in the background

Multiple tasks scheduled for the same time will be executed sequentially, based on the order in which they were defined. Long-running tasks can cause subsequent tasks to start much later than expected. To execute a long task without having to wait for it to start, you should use the runInBackground() method, which allows for background execution. Example:

$scheduler->call('mytask6', function () { ... })->at(14, 30)->runInBackground(true); $scheduler->call('mytask7', function () { ... })->at(14, 30)->runInBackground(true);

Tasks will continue to be executed in the order in which they were declared. This means that background tasks will also be invoked in that same order; if a non-background task precedes them, the background task will have to wait. To execute background tasks ahead of schedule, use:

$scheduler->prioritizeBackgroundTasks(true);

Changing timeZone

By default, all tasks are executed based on UTC, but it is possible to explicitly configure the once() method to execute a task at a specific time:

use Inphinit\Experimental\Scheduling\Task; $dt = new DateTime('2030-01-01', new DateTimeZone('America/New_York')); // It will execute on 2030-01-01 at 12:00:00 $scheduler->call('mytask3', function (Task $task) { echo 'Hello World!'; })->once($dt);

To set the time zone for all tasks, the method to use is $scheduler->setTimeZone() in system/console.php, as shown in the example:

$time_zone = new DateTimeZone('America/New_York'); $scheduler->setTimeZone($time_zone); // Runs every day at 10:00 AM New York time. $scheduler->call('mytask1', function () { ... })->at(10, 0); // Runs every day at 3:30 PM São Paulo time. $scheduler->call('mytask2', function () { ... })->at(15, 30); // Runs every day at 8:00 PM New York time. $scheduler->call('mytask3', function () { ... })->at(20, 0);

Examples of usage

The ::cron() method is similar to the crontab structure, as can be seen in the examples:

$scheduler->call('mytask1', function () { ... })->cron($minute, $hour, $day, $month, $weekday);

Examples:

Usage Explanation
cron('*', '*', '*', '*', '*') Runs every minute. The five fields are set to *, meaning any minute, any hour, any day of the month, any month, and any day of the week.
cron('*/5', '*', '*', '*', '*') Runs every 5 minutes. */5 in the minute field means 0, 5, 10, 15, etc.
cron(0, '*', '*', '*', '*') Runs at minute 0 of every hour—that is, once per hour.
cron(30, 8, '*', '*', '*') Runs every day at 08:30. 30 represents the minute and 8 represents the hour.
cron(0, 0, '*', '*', '*') Runs every day at midnight. 0 in the minute field and 0 in the hour field.
cron(0, 12, '*', '*', 1) Runs every Monday at noon. 1 represents Monday in traditional cron implementations.
cron(0, 9, '*', '*', '1-5') Runs from Monday to Friday at 09:00. 1-5 represents the range from Monday to Friday.
cron(0, 18, '*', '*', '6,0') Runs on Saturdays and Sundays at 18:00. 6,0 represents Saturday and Sunday in cron syntax where Sunday is 0.
cron(0, 0, 1, '*', '*') Runs on the first day of every month at midnight. The third field, 1, is the day of the month.
cron(30, 7, 15, '*', '*') Runs on the 15th of every month at 07:30.
cron(0, 10, '*', 1, '*') Runs every day in January at 10:00. 1 in the month field represents January.
cron(0, 0, 1, 1, '*') Runs at midnight on January 1st.
cron(15, 14, 1, '*', 5) Runs at 14:15 when it is the 1st and a Friday, subject to the specific cron implementation's semantics.
cron(0, '*/2', '*', '*', '*') Runs every 2 hours, always at minute zero: 00:00, 02:00, 04:00, etc.
cron('*/10', '9-17', '*', '*', '1-5') Runs every 10 minutes, between 09:00 and 17:59, Monday through Friday.
cron(0, 0, '*', '*', 0) Runs every Sunday at midnight. 0 in the fifth field represents Sunday in traditional cron.
cron(0, 0, '*', '*', '1,3,5') Runs at midnight on Mondays, Wednesdays, and Fridays. The comma allows you to specify multiple values.
cron(0, 0, '1-7', '*', 1) Runs at midnight on Mondays that fall between the 1st and the 7th of the month.
cron(0, 0, 1, '*/3', '*') Runs on the first day of every third month, at midnight. */3 in the month field represents three-month intervals.
cron(30, 15, '*', '*', '*') Runs every day at 15:30. This is a simple example to visualize the minute (30) and hour (15) separately.