mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Doc: [cronjob manager] Doc for implementing cronjob
This commit is contained in:
parent
17461aa21e
commit
0bfb5c617e
93
docs/source/development/cronjob.rst
Normal file
93
docs/source/development/cronjob.rst
Normal file
@ -0,0 +1,93 @@
|
||||
|
||||
.. 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;
|
||||
|
||||
class MyCronJob implements CronJobInterface
|
||||
{
|
||||
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 = new DateTimeImmutable('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(): void
|
||||
{
|
||||
// here, we execute the command
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
@ -34,6 +34,7 @@ As Chill rely on the `symfony <http://symfony.com>`_ framework, reading the fram
|
||||
Useful snippets <useful-snippets.rst>
|
||||
manual/index.rst
|
||||
Assets <assets.rst>
|
||||
Cron Jobs <cronjob.rst>
|
||||
|
||||
Layout and UI
|
||||
**************
|
||||
|
@ -1,10 +1,12 @@
|
||||
.. Copyright (C) 2014-2019 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".
|
||||
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".
|
||||
|
||||
.. _prod:
|
||||
|
||||
Installation for production
|
||||
###########################
|
||||
@ -36,6 +38,19 @@ This should be adapted to your needs:
|
||||
|
||||
* Think about how you will backup your database. Some adminsys find easier to store database outside of docker, which might be easier to administrate or replicate.
|
||||
|
||||
Cron jobs
|
||||
=========
|
||||
|
||||
The command :code:`chill:cron-job:execute` should be executed every 15 minutes (more or less).
|
||||
|
||||
This command should never be executed concurrently. It should be not have more than one process for a single instance.
|
||||
|
||||
Post-install tasks
|
||||
==================
|
||||
|
||||
- import addresses. See :ref:`addresses`.
|
||||
|
||||
|
||||
Tweak symfony messenger
|
||||
=======================
|
||||
|
||||
|
@ -19,6 +19,25 @@ use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use function array_key_exists;
|
||||
|
||||
/**
|
||||
* Manage cronjob and execute them.
|
||||
*
|
||||
* 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 error inside job execution are catched (with the exception of _out of memory error_).
|
||||
*
|
||||
* The manager will mark the task as executed even if an error is catched. This will lead as failed job
|
||||
* will not have priority any more on other tasks.
|
||||
*
|
||||
* If a tasks is "forced", there is no test about eligibility of the task (the `canRun` method is not called),
|
||||
* and the last task execution is not recorded.
|
||||
*/
|
||||
class CronManager implements CronManagerInterface
|
||||
{
|
||||
private const LOG_PREFIX = '[cron manager] ';
|
||||
|
@ -13,5 +13,11 @@ namespace Chill\MainBundle\Cron;
|
||||
|
||||
interface CronManagerInterface
|
||||
{
|
||||
/**
|
||||
* Execute one job, with a given priority, or the given job (identified by his key)
|
||||
*
|
||||
* @param string|null $forceJob
|
||||
* @return void
|
||||
*/
|
||||
public function run(?string $forceJob = null): void;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user