Skip to content

Commit 1d1d5ec

Browse files
committed
Merge remote-tracking branch 'origin/MAGETWO-88212' into 2.3-PR-develop-1
2 parents fb6620d + 97dd22f commit 1d1d5ec

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

app/code/Magento/Cron/Model/ResourceModel/Schedule.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,14 @@ public function trySetJobUniqueStatusAtomic($scheduleId, $newStatus, $currentSta
6666
{
6767
$connection = $this->getConnection();
6868

69-
$match = $connection->quoteInto('existing.job_code = current.job_code AND existing.status = ?', $newStatus);
69+
// this condition added to avoid cron jobs locking after incorrect termination of running job
70+
$match = $connection->quoteInto(
71+
'existing.job_code = current.job_code ' .
72+
'AND (existing.executed_at > UTC_TIMESTAMP() - INTERVAL 1 DAY OR existing.executed_at IS NULL) ' .
73+
'AND existing.status = ?',
74+
$newStatus
75+
);
76+
7077
$selectIfUnlocked = $connection->select()
7178
->joinLeft(
7279
['existing' => $this->getTable('cron_schedule')],
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Cron\Setup;
8+
9+
use Magento\Framework\Setup\InstallSchemaInterface;
10+
use Magento\Framework\Setup\ModuleContextInterface;
11+
use Magento\Framework\Setup\SchemaSetupInterface;
12+
13+
/**
14+
* Cron recurring setup
15+
*/
16+
class Recurring implements InstallSchemaInterface
17+
{
18+
/**
19+
* @var \Magento\Cron\Model\ResourceModel\Schedule
20+
*/
21+
private $schedule;
22+
23+
/**
24+
* Recurring constructor.
25+
* @param \Magento\Cron\Model\ResourceModel\Schedule $schedule
26+
*/
27+
public function __construct(
28+
\Magento\Cron\Model\ResourceModel\Schedule $schedule
29+
) {
30+
$this->schedule = $schedule;
31+
}
32+
33+
/**
34+
* {@inheritdoc}
35+
*/
36+
public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
37+
{
38+
$connection = $this->schedule->getConnection();
39+
$connection->update(
40+
$this->schedule->getMainTable(),
41+
[
42+
'status' => \Magento\Cron\Model\Schedule::STATUS_ERROR,
43+
'messages' => 'The job is terminated due to system upgrade'
44+
],
45+
$connection->quoteInto('status = ?', \Magento\Cron\Model\Schedule::STATUS_RUNNING)
46+
);
47+
}
48+
}

dev/tests/integration/testsuite/Magento/Cron/Model/ScheduleTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,27 @@ public function testTryLockJobAlreadyLockedFails()
5454
$this->assertFalse($schedule->tryLockJob());
5555
}
5656

57+
/**
58+
* If the job is already locked but lock time less than 1 day ago, attempting to lock it again should fail
59+
*/
60+
public function testTryLockJobAlreadyLockedSucceeds()
61+
{
62+
$offsetInThePast = 2*24*60*60;
63+
64+
$oldSchedule = $this->scheduleFactory->create()
65+
->setCronExpr("* * * * *")
66+
->setJobCode("test_job")
67+
->setStatus(Schedule::STATUS_RUNNING)
68+
->setCreatedAt(strftime('%Y-%m-%d %H:%M:%S', $this->dateTime->gmtTimestamp() - $offsetInThePast))
69+
->setScheduledAt(strftime('%Y-%m-%d %H:%M', $this->dateTime->gmtTimestamp() - $offsetInThePast + 60))
70+
->setExecutedAt(strftime('%Y-%m-%d %H:%M', $this->dateTime->gmtTimestamp() - $offsetInThePast + 61));
71+
$oldSchedule->save();
72+
73+
$schedule = $this->createSchedule("test_job", Schedule::STATUS_PENDING);
74+
75+
$this->assertTrue($schedule->tryLockJob());
76+
}
77+
5778
/**
5879
* If there's a job already locked, should not be able to lock another job
5980
*/

0 commit comments

Comments
 (0)