Skip to content

Commit

Permalink
N°4692 - Enable parallelization of multiple CRON jobs
Browse files Browse the repository at this point in the history
  • Loading branch information
eespie committed Jan 4, 2023
1 parent edec2b2 commit 568e6f2
Showing 1 changed file with 19 additions and 5 deletions.
24 changes: 19 additions & 5 deletions webservices/cron.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ function RunTask(BackgroundTask $oTask, $iTimeLimit)
}

/**
*
* @param bool $bDebug
*
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
Expand All @@ -185,9 +187,19 @@ function CronExec($bDebug)
$iMaxDuration = MetaModel::GetConfig()->Get('cron_max_execution_time');
$iTimeLimit = $iStarted + $iMaxDuration;
$iCronSleep = MetaModel::GetConfig()->Get('cron_sleep');
$iMaxCronProcess = MetaModel::GetConfig()->Get('cron.max_processes');
$iMaxCronProcess = max(MetaModel::GetConfig()->Get('cron.max_processes'), 1);

// Allow a time slot for every task
// knowing that there are $iMaxCronProcess running in parallel for the amount of tasks
$oSearch = new DBObjectSearch('BackgroundTask');
$oSearch->AddCondition('status', 'active');
$oTasks = new DBObjectSet($oSearch);
$iCount = $oTasks->Count();
$iTotalAvailableTime = $iMaxDuration * $iMaxCronProcess;
$iTimeSlot = (int)($iTotalAvailableTime / max($iCount, 1));

CronLog::Debug("Planned duration = $iMaxDuration seconds");
CronLog::Debug("Planned duration per task = $iTimeSlot seconds");
CronLog::Debug("Loop pause = $iCronSleep seconds");

ReSyncProcesses($bDebug);
Expand Down Expand Up @@ -226,7 +238,7 @@ function CronExec($bDebug)
CronLog::Debug($sDebugMessage);
}
$aRunTasks = [];
while ($aTasks != []) {
while (count($aTasks) > 0) {
$oTask = array_shift($aTasks);

$sTaskClass = $oTask->Get('class_name');
Expand All @@ -241,15 +253,17 @@ function CronExec($bDebug)
$aRunTasks[] = $sTaskClass;

// N°3219 for each process will use a specific CMDBChange object with a specific track info
// Any BackgroundProcess can overrides this as needed
// Any BackgroundProcess can override this as needed
CMDBObject::SetCurrentChangeFromParams("Background task ($sTaskClass)");

// Run the task and record its next run time
$oNow = new DateTime();
CronLog::Debug(">> === ".$oNow->format('Y-m-d H:i:s').sprintf(" Start task:%-'=49s", ' '.$sTaskClass.' '));
try
{
$sMessage = RunTask($oTask, $iTimeLimit);
// The limit of time for this task corresponds to the time slot allowed for every task
// but limited to the cron job time limit
$sMessage = RunTask($oTask, min($iTimeLimit, time() + $iTimeSlot));
} catch (MySQLHasGoneAwayException $e)
{
CronLog::Error("ERROR : 'MySQL has gone away' thrown when processing $sTaskClass (error_code=".$e->getCode().")");
Expand Down Expand Up @@ -543,7 +557,7 @@ function ReSyncProcesses($bDebug)
else
{
// Limit the number of cron process to run in parallel
$iMaxCronProcess = MetaModel::GetConfig()->Get('cron.max_processes');
$iMaxCronProcess = max(MetaModel::GetConfig()->Get('cron.max_processes'), 1);
$bCanRun = false;
$iProcessNumber = 0;
for ($i = 0; $i < $iMaxCronProcess; $i++) {
Expand Down

0 comments on commit 568e6f2

Please sign in to comment.