From a5d56c8ddefe48067f0fb23f0d5938c16c4aeca1 Mon Sep 17 00:00:00 2001 From: andris-sevcenko Date: Thu, 7 Mar 2019 13:06:04 +0200 Subject: [PATCH] Fixed #3450 --- CHANGELOG-v3.md | 1 + src/services/AssetIndexer.php | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGELOG-v3.md b/CHANGELOG-v3.md index dca2bf6cf50..85fbfd62a19 100644 --- a/CHANGELOG-v3.md +++ b/CHANGELOG-v3.md @@ -13,6 +13,7 @@ - Fixed a bug where the `positionedBefore` element query param was not including direct ancestors in the results. - Fixed a bug where HTML in plugin-supplied field instructions was getting encoded. ([#3928](https://github.com/craftcms/cms/issues/3928)) - Fixed a bug where Craft would prompt for a user’s current password when registering a new user, even if they weren’t assigning any groups or permissions to that user +- Fixed a bug where a race condition could make Asset indexing inconsistent. ([#3450](https://github.com/craftcms/cms/issues/3450)) ## 3.1.16 - 2019-03-05 diff --git a/src/services/AssetIndexer.php b/src/services/AssetIndexer.php index 88ea0b9d642..d63be55324f 100644 --- a/src/services/AssetIndexer.php +++ b/src/services/AssetIndexer.php @@ -233,6 +233,13 @@ public function storeIndexList(array $indexList, string $sessionId, int $volumeI */ public function processIndexForVolume(string $sessionId, int $volumeId, bool $cacheImages = false) { + $mutex = Craft::$app->getMutex(); + $lockName = 'idx--' . $sessionId; + + if (!$mutex->acquire($lockName, 5)) { + throw new Exception('Could not acquire a lock for the indexing sessiong "' . $sessionId . '".'); + } + if (($indexEntryModel = $this->getNextIndexEntry($sessionId, $volumeId)) === null) { return false; } @@ -240,6 +247,8 @@ public function processIndexForVolume(string $sessionId, int $volumeId, bool $ca // Mark as started. $this->updateIndexEntry($indexEntryModel->id, ['inProgress' => true]); + $mutex->release($lockName); + try { $asset = $this->_indexFileByIndexData($indexEntryModel, $cacheImages); $this->updateIndexEntry($indexEntryModel->id, ['completed' => true, 'inProgress' => false, 'recordId' => $asset->id]);