diff --git a/lib/internal/Magento/Framework/Mview/View.php b/lib/internal/Magento/Framework/Mview/View.php index fca827ca2505f..6e48c90ba5e6b 100644 --- a/lib/internal/Magento/Framework/Mview/View.php +++ b/lib/internal/Magento/Framework/Mview/View.php @@ -274,42 +274,63 @@ public function update() $lastVersionId = (int) $this->getState()->getVersionId(); $action = $this->actionFactory->get($this->getActionClass()); + $this->executeAction($action, $lastVersionId, $currentVersionId); + try { $this->getState()->setStatus(View\StateInterface::STATUS_WORKING)->save(); - $versionBatchSize = self::$maxVersionQueryBatch; - $batchSize = isset($this->changelogBatchSize[$this->getChangelog()->getViewId()]) - ? $this->changelogBatchSize[$this->getChangelog()->getViewId()] - : self::DEFAULT_BATCH_SIZE; - - for ($versionFrom = $lastVersionId; $versionFrom < $currentVersionId; $versionFrom += $versionBatchSize) { - // Don't go past the current version for atomicy. - $versionTo = min($currentVersionId, $versionFrom + $versionBatchSize); - $ids = array_map('intval', $this->getChangelog()->getList($versionFrom, $versionTo)); - - // We run the actual indexer in batches. Chunked AFTER loading to avoid duplicates in separate chunks. - $chunks = array_chunk($ids, $batchSize); - foreach ($chunks as $ids) { - $action->execute($ids); - } - } - $this->getState()->loadByView($this->getId()); $statusToRestore = $this->getState()->getStatus() == View\StateInterface::STATUS_SUSPENDED ? View\StateInterface::STATUS_SUSPENDED : View\StateInterface::STATUS_IDLE; $this->getState()->setVersionId($currentVersionId)->setStatus($statusToRestore)->save(); - } catch (\Exception $exception) { + } catch (\Throwable $exception) { $this->getState()->loadByView($this->getId()); $statusToRestore = $this->getState()->getStatus() == View\StateInterface::STATUS_SUSPENDED ? View\StateInterface::STATUS_SUSPENDED : View\StateInterface::STATUS_IDLE; $this->getState()->setStatus($statusToRestore)->save(); + if (!$exception instanceof \Exception) { + $exception = new \RuntimeException( + 'Error when updating an mview', + 0, + $exception + ); + } throw $exception; } } } + /** + * Execute action from last version to current version, by batches + * + * @param ActionInterface $action + * @param int $lastVersionId + * @param int $currentVersionId + * @return void + * @throws \Exception + */ + private function executeAction(ActionInterface $action, int $lastVersionId, int $currentVersionId) + { + $versionBatchSize = self::$maxVersionQueryBatch; + $batchSize = isset($this->changelogBatchSize[$this->getChangelog()->getViewId()]) + ? $this->changelogBatchSize[$this->getChangelog()->getViewId()] + : self::DEFAULT_BATCH_SIZE; + + for ($versionFrom = $lastVersionId; $versionFrom < $currentVersionId; $versionFrom += $versionBatchSize) { + // Don't go past the current version for atomicy. + $versionTo = min($currentVersionId, $versionFrom + $versionBatchSize); + $ids = array_map('intval', $this->getChangelog()->getList($versionFrom, $versionTo)); + + // We run the actual indexer in batches. Chunked AFTER loading to avoid duplicates in separate chunks. + $chunks = array_chunk($ids, $batchSize); + foreach ($chunks as $ids) { + $action->execute($ids); + } + } + } + /** * Suspend view updates and set version ID to changelog's end *