Skip to content

Commit 3028d55

Browse files
authored
ENGCOM-5335: Added function to check against running/pending/successful cron tasks #23312
2 parents 7fa4b0d + 18e1e19 commit 3028d55

File tree

1 file changed

+59
-25
lines changed

1 file changed

+59
-25
lines changed

app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6-
76
/**
87
* Handling cron jobs
98
*/
109
namespace Magento\Cron\Observer;
1110

11+
use Magento\Cron\Model\Schedule;
1212
use Magento\Framework\App\State;
1313
use Magento\Framework\Console\Cli;
1414
use Magento\Framework\Event\ObserverInterface;
15-
use Magento\Cron\Model\Schedule;
1615
use Magento\Framework\Profiler\Driver\Standard\Stat;
1716
use Magento\Framework\Profiler\Driver\Standard\StatFactory;
1817

@@ -204,7 +203,6 @@ public function __construct(
204203
*/
205204
public function execute(\Magento\Framework\Event\Observer $observer)
206205
{
207-
208206
$currentTime = $this->dateTime->gmtTimestamp();
209207
$jobGroupsRoot = $this->_config->getJobs();
210208
// sort jobs groups to start from used in separated process
@@ -258,7 +256,6 @@ function ($groupId) use ($currentTime, $jobsRoot) {
258256
*/
259257
private function lockGroup($groupId, callable $callback)
260258
{
261-
262259
if (!$this->lockManager->lock(self::LOCK_PREFIX . $groupId, self::LOCK_TIMEOUT)) {
263260
$this->logger->warning(
264261
sprintf(
@@ -293,17 +290,20 @@ protected function _runJob($scheduledTime, $currentTime, $jobConfig, $schedule,
293290
$scheduleLifetime = $scheduleLifetime * self::SECONDS_IN_MINUTE;
294291
if ($scheduledTime < $currentTime - $scheduleLifetime) {
295292
$schedule->setStatus(Schedule::STATUS_MISSED);
293+
// phpcs:ignore Magento2.Exceptions.DirectThrow
296294
throw new \Exception(sprintf('Cron Job %s is missed at %s', $jobCode, $schedule->getScheduledAt()));
297295
}
298296

299297
if (!isset($jobConfig['instance'], $jobConfig['method'])) {
300298
$schedule->setStatus(Schedule::STATUS_ERROR);
299+
// phpcs:ignore Magento2.Exceptions.DirectThrow
301300
throw new \Exception(sprintf('No callbacks found for cron job %s', $jobCode));
302301
}
303302
$model = $this->_objectManager->create($jobConfig['instance']);
304303
$callback = [$model, $jobConfig['method']];
305304
if (!is_callable($callback)) {
306305
$schedule->setStatus(Schedule::STATUS_ERROR);
306+
// phpcs:ignore Magento2.Exceptions.DirectThrow
307307
throw new \Exception(
308308
sprintf('Invalid callback: %s::%s can\'t be called', $jobConfig['instance'], $jobConfig['method'])
309309
);
@@ -314,15 +314,18 @@ protected function _runJob($scheduledTime, $currentTime, $jobConfig, $schedule,
314314
$this->startProfiling();
315315
try {
316316
$this->logger->info(sprintf('Cron Job %s is run', $jobCode));
317+
//phpcs:ignore Magento2.Functions.DiscouragedFunction
317318
call_user_func_array($callback, [$schedule]);
318319
} catch (\Throwable $e) {
319320
$schedule->setStatus(Schedule::STATUS_ERROR);
320-
$this->logger->error(sprintf(
321-
'Cron Job %s has an error: %s. Statistics: %s',
322-
$jobCode,
323-
$e->getMessage(),
324-
$this->getProfilingStat()
325-
));
321+
$this->logger->error(
322+
sprintf(
323+
'Cron Job %s has an error: %s. Statistics: %s',
324+
$jobCode,
325+
$e->getMessage(),
326+
$this->getProfilingStat()
327+
)
328+
);
326329
if (!$e instanceof \Exception) {
327330
$e = new \RuntimeException(
328331
'Error when running a cron job',
@@ -335,16 +338,22 @@ protected function _runJob($scheduledTime, $currentTime, $jobConfig, $schedule,
335338
$this->stopProfiling();
336339
}
337340

338-
$schedule->setStatus(Schedule::STATUS_SUCCESS)->setFinishedAt(strftime(
339-
'%Y-%m-%d %H:%M:%S',
340-
$this->dateTime->gmtTimestamp()
341-
));
341+
$schedule->setStatus(
342+
Schedule::STATUS_SUCCESS
343+
)->setFinishedAt(
344+
strftime(
345+
'%Y-%m-%d %H:%M:%S',
346+
$this->dateTime->gmtTimestamp()
347+
)
348+
);
342349

343-
$this->logger->info(sprintf(
344-
'Cron Job %s is successfully finished. Statistics: %s',
345-
$jobCode,
346-
$this->getProfilingStat()
347-
));
350+
$this->logger->info(
351+
sprintf(
352+
'Cron Job %s is successfully finished. Statistics: %s',
353+
$jobCode,
354+
$this->getProfilingStat()
355+
)
356+
);
348357
}
349358

350359
/**
@@ -395,6 +404,28 @@ private function getPendingSchedules($groupId)
395404
return $pendingJobs;
396405
}
397406

407+
/**
408+
* Return job collection from database with status 'pending', 'running' or 'success'
409+
*
410+
* @param string $groupId
411+
* @return \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
412+
*/
413+
private function getNonExitedSchedules($groupId)
414+
{
415+
$jobs = $this->_config->getJobs();
416+
$pendingJobs = $this->_scheduleFactory->create()->getCollection();
417+
$pendingJobs->addFieldToFilter(
418+
'status',
419+
[
420+
'in' => [
421+
Schedule::STATUS_PENDING, Schedule::STATUS_RUNNING, Schedule::STATUS_SUCCESS
422+
]
423+
]
424+
);
425+
$pendingJobs->addFieldToFilter('job_code', ['in' => array_keys($jobs[$groupId])]);
426+
return $pendingJobs;
427+
}
428+
398429
/**
399430
* Generate cron schedule
400431
*
@@ -426,7 +457,7 @@ private function generateSchedules($groupId)
426457
null
427458
);
428459

429-
$schedules = $this->getPendingSchedules($groupId);
460+
$schedules = $this->getNonExitedSchedules($groupId);
430461
$exists = [];
431462
/** @var Schedule $schedule */
432463
foreach ($schedules as $schedule) {
@@ -669,11 +700,14 @@ private function cleanupScheduleMismatches()
669700
/** @var \Magento\Cron\Model\ResourceModel\Schedule $scheduleResource */
670701
$scheduleResource = $this->_scheduleFactory->create()->getResource();
671702
foreach ($this->invalid as $jobCode => $scheduledAtList) {
672-
$scheduleResource->getConnection()->delete($scheduleResource->getMainTable(), [
673-
'status = ?' => Schedule::STATUS_PENDING,
674-
'job_code = ?' => $jobCode,
675-
'scheduled_at in (?)' => $scheduledAtList,
676-
]);
703+
$scheduleResource->getConnection()->delete(
704+
$scheduleResource->getMainTable(),
705+
[
706+
'status = ?' => Schedule::STATUS_PENDING,
707+
'job_code = ?' => $jobCode,
708+
'scheduled_at in (?)' => $scheduledAtList,
709+
]
710+
);
677711
}
678712
return $this;
679713
}

0 commit comments

Comments
 (0)