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