Skip to content

Making message lock release possible #26968

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 2.4-develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 63 additions & 30 deletions app/code/Magento/MessageQueue/Model/ResourceModel/Lock.php
Original file line number Diff line number Diff line change
@@ -1,29 +1,42 @@
<?php

declare(strict_types=1);

/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\MessageQueue\Model\ResourceModel;

use \Magento\Framework\MessageQueue\Lock\ReaderInterface;
use \Magento\Framework\MessageQueue\Lock\WriterInterface;
use DateInterval;
use DateTime;
use Exception;
use Magento\Framework\MessageQueue\Lock\ReaderInterface;
use Magento\Framework\MessageQueue\Lock\WriterInterface;
use Magento\Framework\MessageQueue\LockInterface;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
use Magento\Framework\Model\ResourceModel\Db\Context;
use Magento\Framework\Stdlib\DateTime\DateTime as MagentoDateTime;
use Magento\MessageQueue\Model\Lock as LockModel;
use Magento\MessageQueue\Model\LockFactory;

/**
* Class Lock to handle database lock table db transactions.
*/
class Lock extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb implements ReaderInterface, WriterInterface
class Lock extends AbstractDb implements ReaderInterface, WriterInterface
{
/**#@+
* Constants
/**
* @var string
*/
const QUEUE_LOCK_TABLE = 'queue_lock';
/**#@-*/
private const QUEUE_LOCK_TABLE = 'queue_lock';

/**#@-*/
/**
* @var MagentoDateTime
*/
private $dateTime;

/**
* @var \Magento\MessageQueue\Model\LockFactory
* @var LockFactory
*/
private $lockFactory;

Expand All @@ -35,18 +48,18 @@ class Lock extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb implemen
/**
* Initialize dependencies.
*
* @param \Magento\Framework\Model\ResourceModel\Db\Context $context
* @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime
* @param \Magento\MessageQueue\Model\LockFactory $lockFactory
* @param null $connectionName
* @param Context $context
* @param MagentoDateTime $dateTime
* @param LockFactory $lockFactory
* @param string|null $connectionName
* @param integer $interval
*/
public function __construct(
\Magento\Framework\Model\ResourceModel\Db\Context $context,
\Magento\Framework\Stdlib\DateTime\DateTime $dateTime,
\Magento\MessageQueue\Model\LockFactory $lockFactory,
$connectionName = null,
$interval = 86400
Context $context,
MagentoDateTime $dateTime,
LockFactory $lockFactory,
?string $connectionName = null,
int $interval = 86400
) {
$this->lockFactory = $lockFactory;
$this->interval = $interval;
Expand All @@ -55,43 +68,63 @@ public function __construct(
}

/**
* {@inheritDoc}
* Init.
*
* @return void
*
* @codeCoverageIgnore
* @SuppressWarnings(PHPMD.CamelCaseMethodName)
*/
protected function _construct()
protected function _construct(): void
{
$this->_init(self::QUEUE_LOCK_TABLE, 'id');
}

/**
* {@inheritDoc}
* Read lock
*
* @param LockInterface $lock
* @param string $code
* @return void
*/
public function read(\Magento\Framework\MessageQueue\LockInterface $lock, $code)
public function read(LockInterface $lock, string $code): void
{
/** @var $object LockModel */
$object = $this->lockFactory->create();
$object->load($code, 'message_code');
$this->load($object, $code, 'message_code');
$lock->setId($object->getId());
$lock->setMessageCode($object->getMessageCode() ?: $code);
$lock->setCreatedAt($object->getCreatedAt());
}

/**
* {@inheritDoc}
* Save lock
*
* @param LockInterface $lock
*
* @return void
* @throws Exception
*/
public function saveLock(\Magento\Framework\MessageQueue\LockInterface $lock)
public function saveLock(LockInterface $lock): void
{
/** @var $object LockModel */
$object = $this->lockFactory->create();
$object->setMessageCode($lock->getMessageCode());
$object->setCreatedAt($this->dateTime->gmtTimestamp());
$object->save();
$this->save($object);
$lock->setId($object->getId());
}

/**
* {@inheritDoc}
* Remove outdated locks
*
* @return void
* @throws Exception
*/
public function releaseOutdatedLocks()
public function releaseOutdatedLocks(): void
{
$date = (new \DateTime())->setTimestamp($this->dateTime->gmtTimestamp());
$date->add(new \DateInterval('PT' . $this->interval . 'S'));
$date = (new DateTime())->setTimestamp($this->dateTime->gmtTimestamp());
$date->add(new DateInterval('PT' . $this->interval . 'S'));
$this->getConnection()->delete($this->getTable(self::QUEUE_LOCK_TABLE), ['created_at <= ?' => $date]);
}
}
Original file line number Diff line number Diff line change
@@ -1,54 +1,68 @@
<?php

declare(strict_types=1);

/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\MessageQueue\Model\Plugin\ResourceModel;

use Magento\TestFramework\Event\Magento;
use Magento\Framework\App\MaintenanceMode;
use Magento\Framework\MessageQueue\Lock\ReaderInterface;
use Magento\Framework\MessageQueue\Lock\WriterInterface;
use Magento\Framework\MessageQueue\LockInterface;
use Magento\Framework\ObjectManagerInterface;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;

class LockTest extends \PHPUnit\Framework\TestCase
class LockTest extends TestCase
{
/**
* @var \Magento\Framework\ObjectManagerInterface
* @var ObjectManagerInterface
*/
protected $objectManager;

/**
* @var \Magento\Framework\MessageQueue\LockInterface
* @var LockInterface
*/
protected $lock;

/**
* @var \Magento\Framework\MessageQueue\Lock\WriterInterface
* @var WriterInterface
*/
protected $writer;

/**
* @var \Magento\Framework\MessageQueue\Lock\ReaderInterface
* @var ReaderInterface
*/
protected $reader;

protected function setUp()
/**
* @return void
*/
protected function setUp(): void
{
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
$this->objectManager = Bootstrap::getObjectManager();

$this->lock = $this->objectManager->get(\Magento\Framework\MessageQueue\LockInterface::class);
$this->writer = $this->objectManager->get(\Magento\Framework\MessageQueue\Lock\WriterInterface::class);
$this->reader = $this->objectManager->get(\Magento\Framework\MessageQueue\Lock\ReaderInterface::class);
$this->lock = $this->objectManager->get(LockInterface::class);
$this->writer = $this->objectManager->get(WriterInterface::class);
$this->reader = $this->objectManager->get(ReaderInterface::class);
}

/**
* Test to ensure Queue Lock Table is cleared when maintenance mode transitions from on to off.
*
* @return void
*/
public function testLockClearedByMaintenanceModeOff()
public function testLockClearedByMaintenanceModeOff(): void
{
/** @var $maintenanceMode \Magento\Framework\App\MaintenanceMode */
$maintenanceMode = $this->objectManager->get(\Magento\Framework\App\MaintenanceMode::class);
/** @var $maintenanceMode MaintenanceMode */
$maintenanceMode = $this->objectManager->get(MaintenanceMode::class);
// phpcs:disable
$code = md5('consumer.name-1');
// phpcs:enable
$this->lock->setMessageCode($code);
$this->writer->saveLock($this->lock);
$this->reader->read($this->lock, $code);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<?php

declare(strict_types=1);

/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Framework\MessageQueue\Lock;

use Magento\Framework\MessageQueue\LockInterface;

/**
* Message lock reader interface
*/
Expand All @@ -13,9 +18,9 @@ interface ReaderInterface
/**
* Get lock from storage
*
* @param \Magento\Framework\MessageQueue\LockInterface $lock
* @param LockInterface $lock
* @param string $code
* @return void
*/
public function read(\Magento\Framework\MessageQueue\LockInterface $lock, $code);
public function read(LockInterface $lock, string $code): void;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<?php

declare(strict_types=1);

/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Framework\MessageQueue\Lock;

use Magento\Framework\MessageQueue\LockInterface;

/**
* Message lock writer
*/
Expand All @@ -13,15 +18,15 @@ interface WriterInterface
/**
* Save lock
*
* @param \Magento\Framework\MessageQueue\LockInterface $lock
* @param LockInterface $lock
* @return void
*/
public function saveLock(\Magento\Framework\MessageQueue\LockInterface $lock);
public function saveLock(LockInterface $lock): void;

/**
* Remove outdated locks
*
* @return void
*/
public function releaseOutdatedLocks();
public function releaseOutdatedLocks(): void;
}