From 7859a2fafe944d0001f663b8502143202dea0216 Mon Sep 17 00:00:00 2001 From: Douglas Radburn Date: Tue, 18 Jun 2019 15:55:02 +0100 Subject: [PATCH 1/2] Added function to check against running/pending/successful cron tasks Added type missing for static call Updated static code tests again --- .../Observer/ProcessCronQueueObserver.php | 62 ++++++++++++++----- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php b/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php index 4bb5dc196f985..a8b43e396785d 100644 --- a/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php +++ b/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php @@ -335,16 +335,21 @@ protected function _runJob($scheduledTime, $currentTime, $jobConfig, $schedule, $this->stopProfiling(); } - $schedule->setStatus(Schedule::STATUS_SUCCESS)->setFinishedAt(strftime( - '%Y-%m-%d %H:%M:%S', - $this->dateTime->gmtTimestamp() - )); - - $this->logger->info(sprintf( - 'Cron Job %s is successfully finished. Statistics: %s', - $jobCode, - $this->getProfilingStat() - )); + $schedule->setStatus( + Schedule::STATUS_SUCCESS)->setFinishedAt( + strftime( + '%Y-%m-%d %H:%M:%S', + $this->dateTime->gmtTimestamp() + ) + ); + + $this->logger->info( + sprintf( + 'Cron Job %s is successfully finished. Statistics: %s', + $jobCode, + $this->getProfilingStat() + ) + ); } /** @@ -395,6 +400,28 @@ private function getPendingSchedules($groupId) return $pendingJobs; } + /** + * Return job collection from database with status 'pending', 'running' or 'success' + * + * @param string $groupId + * @return \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection + */ + private function getNonExitedSchedules($groupId) + { + $jobs = $this->_config->getJobs(); + $pendingJobs = $this->_scheduleFactory->create()->getCollection(); + $pendingJobs->addFieldToFilter( + 'status', + [ + 'in' => [ + Schedule::STATUS_PENDING, Schedule::STATUS_RUNNING, Schedule::STATUS_SUCCESS + ] + ] + ); + $pendingJobs->addFieldToFilter('job_code', ['in' => array_keys($jobs[$groupId])]); + return $pendingJobs; + } + /** * Generate cron schedule * @@ -426,7 +453,7 @@ private function generateSchedules($groupId) null ); - $schedules = $this->getPendingSchedules($groupId); + $schedules = $this->getNonExitedSchedules($groupId); $exists = []; /** @var Schedule $schedule */ foreach ($schedules as $schedule) { @@ -669,11 +696,14 @@ private function cleanupScheduleMismatches() /** @var \Magento\Cron\Model\ResourceModel\Schedule $scheduleResource */ $scheduleResource = $this->_scheduleFactory->create()->getResource(); foreach ($this->invalid as $jobCode => $scheduledAtList) { - $scheduleResource->getConnection()->delete($scheduleResource->getMainTable(), [ - 'status = ?' => Schedule::STATUS_PENDING, - 'job_code = ?' => $jobCode, - 'scheduled_at in (?)' => $scheduledAtList, - ]); + $scheduleResource->getConnection()->delete( + $scheduleResource->getMainTable(), + [ + 'status = ?' => Schedule::STATUS_PENDING, + 'job_code = ?' => $jobCode, + 'scheduled_at in (?)' => $scheduledAtList, + ] + ); } return $this; } From 8ee5163c3e031522b3fc2091a6703d1bac581297 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky Date: Fri, 21 Jun 2019 12:54:39 +0300 Subject: [PATCH 2/2] magento/magento2#23312: Static test fix. --- .../Observer/ProcessCronQueueObserver.php | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php b/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php index a8b43e396785d..5c8aa1dc78abd 100644 --- a/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php +++ b/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php @@ -3,16 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - /** * Handling cron jobs */ namespace Magento\Cron\Observer; +use Magento\Cron\Model\Schedule; use Magento\Framework\App\State; use Magento\Framework\Console\Cli; use Magento\Framework\Event\ObserverInterface; -use Magento\Cron\Model\Schedule; use Magento\Framework\Profiler\Driver\Standard\Stat; use Magento\Framework\Profiler\Driver\Standard\StatFactory; @@ -204,7 +203,6 @@ public function __construct( */ public function execute(\Magento\Framework\Event\Observer $observer) { - $currentTime = $this->dateTime->gmtTimestamp(); $jobGroupsRoot = $this->_config->getJobs(); // sort jobs groups to start from used in separated process @@ -258,7 +256,6 @@ function ($groupId) use ($currentTime, $jobsRoot) { */ private function lockGroup($groupId, callable $callback) { - if (!$this->lockManager->lock(self::LOCK_PREFIX . $groupId, self::LOCK_TIMEOUT)) { $this->logger->warning( sprintf( @@ -293,17 +290,20 @@ protected function _runJob($scheduledTime, $currentTime, $jobConfig, $schedule, $scheduleLifetime = $scheduleLifetime * self::SECONDS_IN_MINUTE; if ($scheduledTime < $currentTime - $scheduleLifetime) { $schedule->setStatus(Schedule::STATUS_MISSED); + // phpcs:ignore Magento2.Exceptions.DirectThrow throw new \Exception(sprintf('Cron Job %s is missed at %s', $jobCode, $schedule->getScheduledAt())); } if (!isset($jobConfig['instance'], $jobConfig['method'])) { $schedule->setStatus(Schedule::STATUS_ERROR); + // phpcs:ignore Magento2.Exceptions.DirectThrow throw new \Exception(sprintf('No callbacks found for cron job %s', $jobCode)); } $model = $this->_objectManager->create($jobConfig['instance']); $callback = [$model, $jobConfig['method']]; if (!is_callable($callback)) { $schedule->setStatus(Schedule::STATUS_ERROR); + // phpcs:ignore Magento2.Exceptions.DirectThrow throw new \Exception( sprintf('Invalid callback: %s::%s can\'t be called', $jobConfig['instance'], $jobConfig['method']) ); @@ -314,15 +314,18 @@ protected function _runJob($scheduledTime, $currentTime, $jobConfig, $schedule, $this->startProfiling(); try { $this->logger->info(sprintf('Cron Job %s is run', $jobCode)); + //phpcs:ignore Magento2.Functions.DiscouragedFunction call_user_func_array($callback, [$schedule]); } catch (\Throwable $e) { $schedule->setStatus(Schedule::STATUS_ERROR); - $this->logger->error(sprintf( - 'Cron Job %s has an error: %s. Statistics: %s', - $jobCode, - $e->getMessage(), - $this->getProfilingStat() - )); + $this->logger->error( + sprintf( + 'Cron Job %s has an error: %s. Statistics: %s', + $jobCode, + $e->getMessage(), + $this->getProfilingStat() + ) + ); if (!$e instanceof \Exception) { $e = new \RuntimeException( 'Error when running a cron job', @@ -336,7 +339,8 @@ protected function _runJob($scheduledTime, $currentTime, $jobConfig, $schedule, } $schedule->setStatus( - Schedule::STATUS_SUCCESS)->setFinishedAt( + Schedule::STATUS_SUCCESS + )->setFinishedAt( strftime( '%Y-%m-%d %H:%M:%S', $this->dateTime->gmtTimestamp() @@ -411,7 +415,7 @@ private function getNonExitedSchedules($groupId) $jobs = $this->_config->getJobs(); $pendingJobs = $this->_scheduleFactory->create()->getCollection(); $pendingJobs->addFieldToFilter( - 'status', + 'status', [ 'in' => [ Schedule::STATUS_PENDING, Schedule::STATUS_RUNNING, Schedule::STATUS_SUCCESS