Ir para o conteúdo principal
Página inicial
Github

Agendamento de tarefas

Aprenda como criar tarefas agendadas que podem ser executadas no estilo crontab, repetidamente ou apenas uma vez.

Configurando

Antes de começar, é necessário configurar o software de agendamento disponível no sistema operacional para executar as tarefas. Se o ambiente usa crontab ou schtasks (Windows) é possivel executar o comando que faz a configuração automizada:

./run schedule:enable

Depois de configurado é possivel remover do crontab ou schtasks de forma automatizada executando:

./run schedule:enable

Configurando manualmente CRON:

Acaso o comando automizado não seja suportado pelo ambiente, ainda é possivel adicionar manualmente no crontab uma instrução semelhante (ajuste os caminhos):

* * * * * /usr/bin/php /path/to/my-app/run schedule:run >> /dev/null 2>&1

Configurando manualmente no Windows:

No Windows o sistema que pode ser usado é o Task Scheduler, via interface gráfica (o que pode ser mais intuitivo) ou via comando, similar a esse:

schtasks /create /tn "My Tasks" /tr "C:\php\php.exe C:\path\to\my-app\run schedule:run" /sc minute /mo 1 /f

Criando tarefas

É possivel agendar funções, comandos existentes, e comandos shell. Para agendar uma função use:

use Inphinit\Experimental\Scheduling\Task; $mytask = $scheduler->call('mytask1', function (Task $task) { echo 'Hello World!'; }); // Define para tarefa a ser executada a cada hora $mytask->interval(3600);

Para agendar um comando existente faça como no exemplo:

// Cria o comando que pode ser executado no terminal `php run sample` $mycommand = $console->action('sample', function (Command $command, array $options, array $residues) { echo 'Hello World!'; }); // Agenda o comando para ser executado conforme a próxima instrução $mytask = $scheduler->command('mytask2', $mycommand); // Configura o agendamento para ser executado a 10 minutos $mytask->interval(600);

Também é possivel agendar comandos arbitrários, com um exemplo para executar vacumm em bancos Postgres de tempos em tempos:

// Define para tarefa a ser executada no dia 1 de todos meses as 03:00 AM (UTC) $scheduler->shell('vacuumdb -d my_database')->cron(0, 3, 1, '*', '*');

Outro exemplo usando o programa systemd-tmpfiles

// Executa limpeza todos dias as 23:30 (UTC) $scheduler->shell('systemd-tmpfiles --clean')->at(23, 30);

Testando tarefa

Para testar uma tarefa, independente do agendamento, basta executar o comando:

./run schedule:run --task mytask1

Configurando o agendamento

Ao adicionar uma tarefa é necessário configurar o momento do disparo e se a execução deve ocorrer em background com os seguintes métodos:

Comando Descrição
cron($minute, $hour, $day, $month, $weekday) Agende a tarefa usando campos no estilo crontab.
interval(int $seconds) Agende a tarefa para ser executada repetidamente a cada intervalo de segundos especificado, contado a partir de sua última execução.
once(string|DateTime $datetime) Agende a tarefa para ser executada exatamente uma vez, na data/hora especificada (ou após ela). Uma vez executada, ela não será mais realizada.
at(int $hour, int $minute) Atalho para agendar a tarefa para execução diária em um horário fixo. Equivalente a cron($minute, $hour, '*', '*', '*').
runInBackground(bool $enable) Marca esta tarefa para ser despachada como um processo em segundo plano independente, em vez de ser executada de forma síncrona dentro do processo do agendador.

Para experimentar, você pode usar funções, closures ou um controller dentro do namespace Tasks, criando um arquivo como system/Tasks/Foo/Bar/BazTask.php e adicionando-o ao system/console.php como:

Como a maioria dos métodos retorna a própria instancia da classe Inphinit\Experimental\Scheduling\Task, é possivel usando como:

$scheduler ->command('mytask', $mycommand) ->cron(30, 16, 1, '*', '*') ->runInBackground(true);

Rodando em background

Diversas tarefas agendadas para o mesmo horário serão executadas sequencialmente, com base na ordem em que foram definidas. Tarefas de longa duração podem fazer com que as tarefas subsequentes iniciem muito mais tarde do que o esperado. Para executar uma tarefa longa sem ter que esperar que ela inicie, você deve usar o método runInBackground(), que permitirá execuções simuladas, por exemplo:

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

Alterando timeZone

Por padrão todas tarefas são executadas baseados em UTC, mas é possivel configurar o método once() explicitamente para executar uma tarefa em uma hora especifica:

use Inphinit\Experimental\Scheduling\Task; $time_zone = new DateTime('2030-01-01', new DateTimeZone('America/Sao_Paulo')); // Executará em 2030-01-01 12:00:00 $scheduler->call('mytask3', function (Task $task) { echo 'Hello World!'; })->once($time_zone);

Para definir timezone para todas tarefas o método a ser usado é $scheduler->setTimeZone() no system/console.php, como no exemplo:

$time_zone = new DateTimeZone('America/Sao_Paulo'); $scheduler->setTimeZone($time_zone); // Executará todos os dias as 10:00 AM do horário de São Paulo $scheduler->call(function () { ... })->at(10, 0); // Executará todos os dias as 15:30 do horário de São Paulo $scheduler->call(function () { ... })->at(15, 30); // Executará todos os dias as 20:00 do horário de São Paulo $scheduler->call(function () { ... })->at(20, 0);