diff --git a/vendor/magento/module-sales/Model/GridAsyncInsert.php b/vendor/magento/module-sales/Model/GridAsyncInsert.php index 43b4b3a5b346d..29a7097b2a0be 100644 --- a/vendor/magento/module-sales/Model/GridAsyncInsert.php +++ b/vendor/magento/module-sales/Model/GridAsyncInsert.php @@ -5,6 +5,9 @@ */ namespace Magento\Sales\Model; +use Magento\Framework\Lock\LockManagerInterface; +use Psr\Log\LoggerInterface; + /** * Sales entity grids indexing observer. * @@ -27,23 +30,46 @@ class GridAsyncInsert */ protected $globalConfig; + /** + * @var LockManagerInterface|null + */ + private $lockManager; + + /** + * @var LoggerInterface|null + */ + private $logger; + + /** + * @var string + */ + private $lockName; + /** * @param \Magento\Sales\Model\ResourceModel\GridInterface $entityGrid * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig + * @param LockManagerInterface|null $lockManager + * @param LoggerInterface|null $logger + * @param string $lockName */ public function __construct( \Magento\Sales\Model\ResourceModel\GridInterface $entityGrid, - \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig + \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig, + ?LockManagerInterface $lockManager = null, + ?LoggerInterface $logger = null, + string $lockName = '' ) { $this->entityGrid = $entityGrid; $this->globalConfig = $globalConfig; + $this->lockManager = $lockManager; + $this->logger = $logger; + $this->lockName = $lockName; } /** - * Handles asynchronous insertion of the new entity into - * corresponding grid during cron job. + * Handles asynchronous insertion of the new entity into corresponding grid during cron job. * - * Also method is used in the next events: + * Also, method is used in the next events: * * - config_data_dev_grid_async_indexing_disabled * @@ -55,7 +81,23 @@ public function __construct( public function asyncInsert() { if ($this->globalConfig->getValue('dev/grid/async_indexing')) { - $this->entityGrid->refreshBySchedule(); + if ($this->lockManager && $this->lockName !== '') { + if (!$this->lockManager->lock($this->lockName, 0)) { + if ($this->logger) { + $this->logger->warning( + sprintf('Grid async insert is locked: %s, skipping run', $this->lockName) + ); + } + return; + } + try { + $this->entityGrid->refreshBySchedule(); + } finally { + $this->lockManager->unlock($this->lockName); + } + } else { + $this->entityGrid->refreshBySchedule(); + } } } } diff --git a/vendor/magento/module-sales/Model/ResourceModel/Grid.php b/vendor/magento/module-sales/Model/ResourceModel/Grid.php index 8da260ded3f3c..061e810b108ee 100644 --- a/vendor/magento/module-sales/Model/ResourceModel/Grid.php +++ b/vendor/magento/module-sales/Model/ResourceModel/Grid.php @@ -54,7 +54,7 @@ class Grid extends AbstractGrid /** * Order grid rows batch size */ - const BATCH_SIZE = 100; + public const BATCH_SIZE = 100; /** * @param Context $context @@ -130,24 +130,26 @@ public function refresh($value, $field = null) public function refreshBySchedule() { $lastUpdatedAt = null; - $notSyncedIds = $this->notSyncedDataProvider->getIds($this->mainTableName, $this->gridTableName); - foreach (array_chunk($notSyncedIds, self::BATCH_SIZE) as $bunch) { - $select = $this->getGridOriginSelect()->where($this->mainTableName . '.entity_id IN (?)', $bunch); - $fetchResult = $this->getConnection()->fetchAll($select); - $this->getConnection()->insertOnDuplicate( - $this->getTable($this->gridTableName), - $fetchResult, - array_keys($this->columns) - ); - - $timestamps = array_column($fetchResult, 'updated_at'); - if ($timestamps) { - $lastUpdatedAt = max(max($timestamps), $lastUpdatedAt); + while (true) { + $notSyncedIds = $this->notSyncedDataProvider->getIds($this->mainTableName, $this->gridTableName); + if (empty($notSyncedIds)) { + break; + } + foreach (array_chunk($notSyncedIds, self::BATCH_SIZE) as $bunch) { + $select = $this->getGridOriginSelect()->where($this->mainTableName . '.entity_id IN (?)', $bunch); + $fetchResult = $this->getConnection()->fetchAll($select); + $this->getConnection()->insertOnDuplicate( + $this->getTable($this->gridTableName), + $fetchResult, + array_keys($this->columns) + ); + + $timestamps = array_column($fetchResult, 'updated_at'); + if ($timestamps) { + $lastUpdatedAt = max(max($timestamps), $lastUpdatedAt); + $this->lastUpdateTimeCache->save($this->gridTableName, $lastUpdatedAt); + } } - } - - if ($lastUpdatedAt) { - $this->lastUpdateTimeCache->save($this->gridTableName, $lastUpdatedAt); } } diff --git a/vendor/magento/module-sales/etc/di.xml b/vendor/magento/module-sales/etc/di.xml index a0bc3d7dc8b3f..c343a8989beb6 100644 --- a/vendor/magento/module-sales/etc/di.xml +++ b/vendor/magento/module-sales/etc/di.xml @@ -267,21 +267,29 @@ Magento\Sales\Model\ResourceModel\Order\Grid + Magento\Framework\Lock\LockManagerInterface + grid_async_insert_sales_order Magento\Sales\Model\ResourceModel\Order\Invoice\Grid + Magento\Framework\Lock\LockManagerInterface + grid_async_insert_sales_invoice ShipmentGridAggregator + Magento\Framework\Lock\LockManagerInterface + grid_async_insert_sales_shipment CreditmemoGridAggregator + Magento\Framework\Lock\LockManagerInterface + grid_async_insert_sales_creditmemo