diff --git a/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php b/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php index f772a6c0c8493..c2faa39f732de 100644 --- a/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php +++ b/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php @@ -61,6 +61,11 @@ class ProcessCronQueueObserver implements ObserverInterface */ protected $_pendingSchedules; + /** + * @var \Magento\Cron\Model\ResourceModel\Schedule\Collection + */ + private $runningSchedules; + /** * @var \Magento\Cron\Model\ConfigInterface */ @@ -214,7 +219,7 @@ public function execute(\Magento\Framework\Event\Observer $observer) /** @var \Magento\Cron\Model\Schedule $schedule */ foreach ($pendingJobs as $schedule) { $jobConfig = isset($jobsRoot[$schedule->getJobCode()]) ? $jobsRoot[$schedule->getJobCode()] : null; - if (!$jobConfig) { + if (!$jobConfig || $this->isJobRunning($schedule->getJobCode())) { continue; } @@ -250,6 +255,25 @@ public function execute(\Magento\Framework\Event\Observer $observer) } } + /** + * @param $jobCode + * + * @return bool + */ + private function isJobRunning($jobCode) + { + $runningJobs = $this->getRunningSchedules(); + + /** @var \Magento\Cron\Model\Schedule $schedule */ + foreach ($runningJobs as $schedule) { + if ($schedule->getData('job_code') == $jobCode) { + return true; + } + } + + return false; + } + /** * Execute job by calling specific class::method * @@ -317,6 +341,22 @@ protected function _getPendingSchedules() return $this->_pendingSchedules; } + /** + * Return job collection from data base with status 'running' + * + * @return \Magento\Cron\Model\ResourceModel\Schedule\Collection + */ + private function getRunningSchedules() + { + if (!$this->runningSchedules) { + $this->runningSchedules = $this->_scheduleFactory->create()->getCollection()->addFieldToFilter( + 'status', + Schedule::STATUS_RUNNING + )->load(); + } + return $this->runningSchedules; + } + /** * Generate cron schedule * diff --git a/app/code/Magento/Cron/Test/Unit/Observer/ProcessCronQueueObserverTest.php b/app/code/Magento/Cron/Test/Unit/Observer/ProcessCronQueueObserverTest.php index 0db6a598fb56f..83306ade8d11e 100644 --- a/app/code/Magento/Cron/Test/Unit/Observer/ProcessCronQueueObserverTest.php +++ b/app/code/Magento/Cron/Test/Unit/Observer/ProcessCronQueueObserverTest.php @@ -262,7 +262,7 @@ public function testDispatchCanNotLock() )->disableOriginalConstructor()->getMock(); $scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($this->_collection)); $scheduleMock->expects($this->any())->method('getResource')->will($this->returnValue($this->scheduleResource)); - $this->_scheduleFactory->expects($this->exactly(2))->method('create')->will($this->returnValue($scheduleMock)); + $this->_scheduleFactory->expects($this->exactly(3))->method('create')->will($this->returnValue($scheduleMock)); $this->_observer->execute($this->observer); } @@ -333,7 +333,7 @@ public function testDispatchExceptionTooLate() ->disableOriginalConstructor()->getMock(); $scheduleMock->expects($this->any())->method('getCollection')->willReturn($this->_collection); $scheduleMock->expects($this->any())->method('getResource')->will($this->returnValue($this->scheduleResource)); - $this->_scheduleFactory->expects($this->exactly(2))->method('create')->willReturn($scheduleMock); + $this->_scheduleFactory->expects($this->exactly(3))->method('create')->willReturn($scheduleMock); $this->_observer->execute($this->observer); } @@ -388,7 +388,7 @@ public function testDispatchExceptionNoCallback() )->disableOriginalConstructor()->getMock(); $scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($this->_collection)); $scheduleMock->expects($this->any())->method('getResource')->will($this->returnValue($this->scheduleResource)); - $this->_scheduleFactory->expects($this->exactly(2))->method('create')->will($this->returnValue($scheduleMock)); + $this->_scheduleFactory->expects($this->exactly(3))->method('create')->will($this->returnValue($scheduleMock)); $this->_observer->execute($this->observer); } @@ -453,7 +453,7 @@ public function testDispatchExceptionInCallback( )->disableOriginalConstructor()->getMock(); $scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($this->_collection)); $scheduleMock->expects($this->any())->method('getResource')->will($this->returnValue($this->scheduleResource)); - $this->_scheduleFactory->expects($this->exactly(2))->method('create')->will($this->returnValue($scheduleMock)); + $this->_scheduleFactory->expects($this->exactly(3))->method('create')->will($this->returnValue($scheduleMock)); $this->_objectManager ->expects($this->once()) ->method('create') @@ -524,7 +524,7 @@ public function testDispatchRunJob() // cron end execute some job $schedule->expects( - $this->at(6) + $this->at(7) )->method( 'setStatus' )->with( @@ -550,7 +550,7 @@ public function testDispatchRunJob() )->disableOriginalConstructor()->getMock(); $scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($this->_collection)); $scheduleMock->expects($this->any())->method('getResource')->will($this->returnValue($this->scheduleResource)); - $this->_scheduleFactory->expects($this->exactly(2))->method('create')->will($this->returnValue($scheduleMock)); + $this->_scheduleFactory->expects($this->exactly(3))->method('create')->will($this->returnValue($scheduleMock)); $testCronJob = $this->getMockBuilder('CronJob')->setMethods(['execute'])->getMock(); $testCronJob->expects($this->atLeastOnce())->method('execute')->with($schedule);