/
githubmirror
/
magento2
Обзор
Документация
Войти
/
githubmirror
/
magento2
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
2.4-develop
lib/internal/Magento/Framework/Cache/LockGuardedCacheLoader.php
177 строк
5 KB
Dmytro Horytskyi
ACP2E-3673: allow_parallel_generation should be set through environment variable
13 фев 2025, 03:20
13 фев 2025, 03:20
46d7679
Код
Авторство
О чём код?
<?php /** * Copyright 2019 Adobe * All Rights Reserved. */ namespace Magento\Framework\Cache; use Magento\Framework\App\ObjectManager; use Magento\Framework\Lock\LockManagerInterface; use Magento\Framework\App\DeploymentConfig; /** * Default mutex that provide concurrent access to cache storage. */ class LockGuardedCacheLoader { /** * @var LockManagerInterface */ private $locker; /** * Lifetime of the lock for write in cache. * * Value of the variable in milliseconds. * * @var int */ private $lockTimeout; /** * Timeout between retrieves to load the configuration from the cache. * * Value of the variable in milliseconds. * * @var int */ private $delayTimeout; /** * Timeout for information to be collected and saved. * If timeout passed that means that data cannot be saved right now. * And we will just return collected data. * * Value of the variable in milliseconds. * * @var int */ private $loadTimeout; /** * Minimal delay timeout in ms. * * @var int */ private $minimalDelayTimeout; /** * @var DeploymentConfig */ private $deploymentConfig; /** * Option that allows to switch off blocking for parallel generation. * * @var string */ private const CONFIG_PATH_ALLOW_PARALLEL_CACHE_GENERATION = 'cache/allow_parallel_generation'; /** * Config value of parallel generation. * * @var bool|null */ private ?bool $allowParallelGenerationConfigValue; /** * @param LockManagerInterface $locker * @param int $lockTimeout * @param int $delayTimeout * @param int $loadTimeout * @param int $minimalDelayTimeout * @param DeploymentConfig|null $deploymentConfig */ public function __construct( LockManagerInterface $locker, int $lockTimeout = 10000, int $delayTimeout = 20, int $loadTimeout = 10000, int $minimalDelayTimeout = 5, ?DeploymentConfig $deploymentConfig = null ) { $this->locker = $locker; $this->lockTimeout = $lockTimeout; $this->delayTimeout = $delayTimeout; $this->loadTimeout = $loadTimeout; $this->minimalDelayTimeout = $minimalDelayTimeout; $this->deploymentConfig = $deploymentConfig ?? ObjectManager::getInstance()->get(DeploymentConfig::class); } /** * Load data. * * @param string $lockName * @param callable $dataLoader * @param callable $dataCollector * @param callable $dataSaver * @return mixed */ public function lockedLoadData( string $lockName, callable $dataLoader, callable $dataCollector, callable $dataSaver ) { $cachedData = $dataLoader(); //optimistic read $deadline = microtime(true) + $this->loadTimeout / 1000; if (empty($this->allowParallelGenerationConfigValue)) { $this->allowParallelGenerationConfigValue = (bool) $this->deploymentConfig ->get(self::CONFIG_PATH_ALLOW_PARALLEL_CACHE_GENERATION); } while ($cachedData === false) { if ($deadline <= microtime(true)) { return $dataCollector(); } if ($this->locker->lock($lockName, 0)) { try { $data = $dataCollector(); $dataSaver($data); $cachedData = $data; } finally { $this->locker->unlock($lockName); } } elseif ($this->allowParallelGenerationConfigValue) { return $dataCollector(); } if ($cachedData === false) { usleep($this->getLookupTimeout() * 1000); $cachedData = $dataLoader(); } } return $cachedData; } /** * Clean data. * * @param string $lockName * @param callable $dataCleaner * @return void */ public function lockedCleanData(string $lockName, callable $dataCleaner) { while ($this->locker->isLocked($lockName)) { usleep($this->getLookupTimeout() * 1000); } $dataCleaner(); } /** * Delay will be applied as rand($minimalDelayTimeout, $delayTimeout). * This helps to desynchronize multiple clients trying * to acquire the lock for the same resource at the same time * * @return int */ private function getLookupTimeout() { return rand($this->minimalDelayTimeout, $this->delayTimeout); } }