diff --git a/vendor/magento/module-catalog/Model/Indexer/Category/Product.php b/vendor/magento/module-catalog/Model/Indexer/Category/Product.php index f5a8c33cfa6..89a6e6d3c25 100644 --- a/vendor/magento/module-catalog/Model/Indexer/Category/Product.php +++ b/vendor/magento/module-catalog/Model/Indexer/Category/Product.php @@ -5,7 +5,10 @@ */ namespace Magento\Catalog\Model\Indexer\Category; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Indexer\CacheContext; +use Magento\Framework\Indexer\IndexMutexException; +use Magento\Framework\Indexer\IndexMutexInterface; /** * Category product indexer @@ -41,19 +44,27 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr */ protected $cacheContext; + /** + * @var IndexMutexInterface + */ + private $indexMutex; + /** * @param Product\Action\FullFactory $fullActionFactory * @param Product\Action\RowsFactory $rowsActionFactory * @param \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry + * @param IndexMutexInterface|null $indexMutex */ public function __construct( Product\Action\FullFactory $fullActionFactory, Product\Action\RowsFactory $rowsActionFactory, - \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry + \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry, + ?IndexMutexInterface $indexMutex = null ) { $this->fullActionFactory = $fullActionFactory; $this->rowsActionFactory = $rowsActionFactory; $this->indexerRegistry = $indexerRegistry; + $this->indexMutex = $indexMutex ?? ObjectManager::getInstance()->get(IndexMutexInterface::class); } /** @@ -61,6 +72,7 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr * * @param int[] $ids * @return void + * @throws IndexMutexException */ public function execute($ids) { @@ -84,11 +96,17 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr * Execute full indexation * * @return void + * @throws IndexMutexException */ public function executeFull() { - $this->fullActionFactory->create()->execute(); - $this->registerTags(); + $this->indexMutex->execute( + static::INDEXER_ID, + function () { + $this->fullActionFactory->create()->execute(); + $this->registerTags(); + } + ); } /** @@ -107,6 +125,7 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr * * @param int[] $ids * @return void + * @throws IndexMutexException */ public function executeList(array $ids) { @@ -118,6 +137,7 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr * * @param int $id * @return void + * @throws IndexMutexException */ public function executeRow($id) { @@ -129,18 +149,22 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr * * @param int[] $ids * @return $this + * @throws IndexMutexException */ protected function executeAction($ids) { $ids = array_unique($ids); $indexer = $this->indexerRegistry->get(static::INDEXER_ID); - /** @var Product\Action\Rows $action */ - $action = $this->rowsActionFactory->create(); if ($indexer->isScheduled()) { - $action->execute($ids, true); + $this->indexMutex->execute( + static::INDEXER_ID, + function () use ($ids) { + $this->rowsActionFactory->create()->execute($ids, true); + } + ); } else { - $action->execute($ids); + $this->rowsActionFactory->create()->execute($ids); } return $this; diff --git a/vendor/magento/module-catalog/Model/Indexer/Product/Category.php b/vendor/magento/module-catalog/Model/Indexer/Product/Category.php index e50b16837ee..b5ecd1076f9 100644 --- a/vendor/magento/module-catalog/Model/Indexer/Product/Category.php +++ b/vendor/magento/module-catalog/Model/Indexer/Product/Category.php @@ -5,7 +5,11 @@ */ namespace Magento\Catalog\Model\Indexer\Product; +use Magento\Framework\Indexer\IndexMutexInterface; + /** + * Product Categories indexer + * * @api * @since 100.0.2 */ @@ -20,13 +24,17 @@ class Category extends \Magento\Catalog\Model\Indexer\Category\Product * @param \Magento\Catalog\Model\Indexer\Category\Product\Action\FullFactory $fullActionFactory * @param Category\Action\RowsFactory $rowsActionFactory * @param \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry + * @param IndexMutexInterface|null $indexMutex + * phpcs:disable Generic.CodeAnalysis.UselessOverridingMethod.Found */ public function __construct( \Magento\Catalog\Model\Indexer\Category\Product\Action\FullFactory $fullActionFactory, Category\Action\RowsFactory $rowsActionFactory, - \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry + \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry, + ?IndexMutexInterface $indexMutex = null ) { - parent::__construct($fullActionFactory, $rowsActionFactory, $indexerRegistry); + //phpcs:enable + parent::__construct($fullActionFactory, $rowsActionFactory, $indexerRegistry, $indexMutex); } /** diff --git a/vendor/magento/module-indexer/Model/IndexMutex.php b/vendor/magento/module-indexer/Model/IndexMutex.php new file mode 100644 index 00000000000..fd0cf3dc480 --- /dev/null +++ b/vendor/magento/module-indexer/Model/IndexMutex.php @@ -0,0 +1,75 @@ +lockManager = $lockManager; + $this->lockWaitTimeout = $lockWaitTimeout; + $this->config = $config; + } + + /** + * @inheritdoc + */ + public function execute(string $indexerName, callable $callback): void + { + $lockName = $indexerName; + $indexerConfig = $this->config->getIndexer($indexerName); + if (isset($indexerConfig['shared_index'])) { + $lockName = $indexerConfig['shared_index']; + } + + if ($this->lockManager->lock(self::LOCK_PREFIX . $lockName, $this->lockWaitTimeout)) { + try { + $callback(); + } finally { + $this->lockManager->unlock(self::LOCK_PREFIX . $lockName); + } + } else { + throw new IndexMutexException($indexerName); + } + } +} diff --git a/vendor/magento/module-indexer/etc/di.xml b/vendor/magento/module-indexer/etc/di.xml index 9496f29cb1d..d7996ee68a7 100644 --- a/vendor/magento/module-indexer/etc/di.xml +++ b/vendor/magento/module-indexer/etc/di.xml @@ -12,6 +12,7 @@ + diff --git a/vendor/magento/framework/Indexer/IndexMutexException.php b/vendor/magento/framework/Indexer/IndexMutexException.php new file mode 100644 index 00000000000..5148bb2bafd --- /dev/null +++ b/vendor/magento/framework/Indexer/IndexMutexException.php @@ -0,0 +1,24 @@ +