mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
102 lines
3.8 KiB
ReStructuredText
102 lines
3.8 KiB
ReStructuredText
|
|
.. Copyright (C) 2014-2023 Champs Libres Cooperative SCRLFS
|
|
Permission is granted to copy, distribute and/or modify this document
|
|
under the terms of the GNU Free Documentation License, Version 1.3
|
|
or any later version published by the Free Software Foundation;
|
|
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
|
A copy of the license is included in the section entitled "GNU
|
|
Free Documentation License".
|
|
|
|
.. _cronjob:
|
|
|
|
Cron jobs
|
|
*********
|
|
|
|
Some tasks must be executed regularly: refresh some materialized views, remove old data, ...
|
|
|
|
For this purpose, one can programmatically implements a "cron job", which will be scheduled by a specific command.
|
|
|
|
The command :code:`chill:cron-job:execute`
|
|
==========================================
|
|
|
|
The command :code:`chill:cron-job:execute` will schedule a task, one by one. In a classical implementation, it should
|
|
be executed every 15 minutes (more or less), to ensure that every task can be executed.
|
|
|
|
.. warning::
|
|
|
|
This command should not be executed in parallel. The installer should ensure that two job are executed concurrently.
|
|
|
|
How to implements a cron job ?
|
|
==============================
|
|
|
|
Implements a :code:`Chill\MainBundle\Cron\CronJobInterface`. Here is an example:
|
|
|
|
.. code-block:: php
|
|
|
|
namespace Chill\MainBundle\Service\Something;
|
|
|
|
use Chill\MainBundle\Cron\CronJobInterface;
|
|
use Chill\MainBundle\Entity\CronJobExecution;
|
|
use DateInterval;
|
|
use DateTimeImmutable;
|
|
use Symfony\Component\Clock\ClockInterface;
|
|
|
|
class MyCronJob implements CronJobInterface
|
|
{
|
|
function __construct(private ClockInterface $clock) {}
|
|
|
|
public function canRun(?CronJobExecution $cronJobExecution): bool
|
|
{
|
|
// the parameter $cronJobExecution contains data about the last execution of the cronjob
|
|
// if it is null, it should be executed immediatly
|
|
if (null === $cronJobExecution) {
|
|
return true;
|
|
}
|
|
|
|
if ($cronJobExecution->getKey() !== $this->getKey()) {
|
|
throw new UnexpectedValueException();
|
|
}
|
|
|
|
// this cron job should be executed if the last execution is greater than one day, but only during the night
|
|
|
|
$now = $clock->now();
|
|
|
|
return $cronJobExecution->getLastStart() < $now->sub(new DateInterval('P1D'))
|
|
&& in_array($now->format('H'), self::ACCEPTED_HOURS, true)
|
|
// introduce a random component to ensure a roll of task execution when multiple instances are hosted on same machines
|
|
&& mt_rand(0, 5) === 0;
|
|
}
|
|
|
|
public function getKey(): string
|
|
{
|
|
return 'arbitrary-and-unique-key';
|
|
}
|
|
|
|
public function run(array $lastExecutionData): void
|
|
{
|
|
// here, we execute the command
|
|
|
|
// we return execution data, which will be served for next execution
|
|
// this data should be easily serializable in a json column: it should contains
|
|
// only int, string, etc. Avoid storing object
|
|
return ['last-execution-id' => 0];
|
|
}
|
|
}
|
|
|
|
How are cron job scheduled ?
|
|
============================
|
|
|
|
If the command :code:`chill:cron-job:execute` is run with one or more :code:`job` argument, those jobs are run, **without checking that the job can run** (the method :code:`canRun` is not executed).
|
|
|
|
If any :code:`job` argument is given, the :code:`CronManager` schedule job with those steps:
|
|
|
|
* the tasks are ordered, with:
|
|
* a priority is given for tasks that weren't never executed;
|
|
* then, the tasks are ordered, the last executed are the first in the list
|
|
* then, for each tasks, and in the given order, the first task where :code:`canRun` return :code:`TRUE` will be executed.
|
|
|
|
The command :code:`chill:cron-job:execute` execute **only one** task.
|
|
|
|
|
|
|