[Cache] fix LockRegistry
This commit is contained in:
parent
8907650424
commit
f49df4ab05
@ -23,7 +23,7 @@ use Symfony\Contracts\Cache\ItemInterface;
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class LockRegistry
|
||||
final class LockRegistry
|
||||
{
|
||||
private static $openedFiles = [];
|
||||
private static $lockedFiles = [];
|
||||
@ -74,7 +74,7 @@ class LockRegistry
|
||||
return $previousFiles;
|
||||
}
|
||||
|
||||
public static function compute(callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool)
|
||||
public static function compute(callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata = null)
|
||||
{
|
||||
$key = self::$files ? crc32($item->getKey()) % \count(self::$files) : -1;
|
||||
|
||||
@ -88,7 +88,18 @@ class LockRegistry
|
||||
if (flock($lock, LOCK_EX | LOCK_NB)) {
|
||||
self::$lockedFiles[$key] = true;
|
||||
|
||||
return $callback($item, $save);
|
||||
$value = $callback($item, $save);
|
||||
|
||||
if ($save) {
|
||||
if ($setMetadata) {
|
||||
$setMetadata($item);
|
||||
}
|
||||
|
||||
$pool->save($item->set($value));
|
||||
$save = false;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
// if we failed the race, retry locking in blocking mode to wait for the winner
|
||||
flock($lock, LOCK_SH);
|
||||
@ -125,6 +136,6 @@ class LockRegistry
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
self::$openedFiles[$key] = $h ?: @fopen(self::$files[$key], 'r');
|
||||
return self::$openedFiles[$key] = $h ?: @fopen(self::$files[$key], 'r');
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ trait ContractsTrait
|
||||
public function setCallbackWrapper(?callable $callbackWrapper): callable
|
||||
{
|
||||
$previousWrapper = $this->callbackWrapper;
|
||||
$this->callbackWrapper = $callbackWrapper ?? function (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool) {
|
||||
$this->callbackWrapper = $callbackWrapper ?? function (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata) {
|
||||
return $callback($item, $save);
|
||||
};
|
||||
|
||||
@ -56,17 +56,19 @@ trait ContractsTrait
|
||||
static $setMetadata;
|
||||
|
||||
$setMetadata = $setMetadata ?? \Closure::bind(
|
||||
function (AdapterInterface $pool, ItemInterface $item, float $startTime) {
|
||||
function (CacheItem $item, float $startTime, ?array &$metadata) {
|
||||
if ($item->expiry > $endTime = microtime(true)) {
|
||||
$item->newMetadata[ItemInterface::METADATA_EXPIRY] = $item->expiry;
|
||||
$item->newMetadata[ItemInterface::METADATA_CTIME] = 1000 * (int) ($endTime - $startTime);
|
||||
$item->newMetadata[CacheItem::METADATA_EXPIRY] = $metadata[CacheItem::METADATA_EXPIRY] = $item->expiry;
|
||||
$item->newMetadata[CacheItem::METADATA_CTIME] = $metadata[CacheItem::METADATA_CTIME] = 1000 * (int) ($endTime - $startTime);
|
||||
} else {
|
||||
unset($metadata[CacheItem::METADATA_EXPIRY], $metadata[CacheItem::METADATA_CTIME]);
|
||||
}
|
||||
},
|
||||
null,
|
||||
CacheItem::class
|
||||
);
|
||||
|
||||
return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata) {
|
||||
return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata) {
|
||||
// don't wrap nor save recursive calls
|
||||
if (null === $callbackWrapper = $this->callbackWrapper) {
|
||||
$value = $callback($item, $save);
|
||||
@ -78,8 +80,10 @@ trait ContractsTrait
|
||||
$startTime = microtime(true);
|
||||
|
||||
try {
|
||||
$value = $callbackWrapper($callback, $item, $save, $pool);
|
||||
$setMetadata($pool, $item, $startTime);
|
||||
$value = $callbackWrapper($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) {
|
||||
$setMetadata($item, $startTime, $metadata);
|
||||
});
|
||||
$setMetadata($item, $startTime, $metadata);
|
||||
|
||||
return $value;
|
||||
} finally {
|
||||
|
Reference in New Issue
Block a user