summaryrefslogtreecommitdiff
path: root/vendor/symfony/cache/Traits
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/symfony/cache/Traits')
-rw-r--r--vendor/symfony/cache/Traits/AbstractAdapterTrait.php139
-rw-r--r--vendor/symfony/cache/Traits/AbstractTrait.php7
-rw-r--r--vendor/symfony/cache/Traits/ArrayTrait.php5
-rw-r--r--vendor/symfony/cache/Traits/ContractsTrait.php19
-rw-r--r--vendor/symfony/cache/Traits/FilesystemCommonTrait.php4
-rw-r--r--vendor/symfony/cache/Traits/RedisTrait.php63
6 files changed, 196 insertions, 41 deletions
diff --git a/vendor/symfony/cache/Traits/AbstractAdapterTrait.php b/vendor/symfony/cache/Traits/AbstractAdapterTrait.php
new file mode 100644
index 0000000000..eb464c319e
--- /dev/null
+++ b/vendor/symfony/cache/Traits/AbstractAdapterTrait.php
@@ -0,0 +1,139 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+use Psr\Cache\CacheItemInterface;
+use Symfony\Component\Cache\CacheItem;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @internal
+ */
+trait AbstractAdapterTrait
+{
+ use AbstractTrait;
+
+ /**
+ * @var \Closure needs to be set by class, signature is function(string <key>, mixed <value>, bool <isHit>)
+ */
+ private $createCacheItem;
+
+ /**
+ * @var \Closure needs to be set by class, signature is function(array <deferred>, string <namespace>, array <&expiredIds>)
+ */
+ private $mergeByLifetime;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItem($key)
+ {
+ if ($this->deferred) {
+ $this->commit();
+ }
+ $id = $this->getId($key);
+
+ $f = $this->createCacheItem;
+ $isHit = false;
+ $value = null;
+
+ try {
+ foreach ($this->doFetch([$id]) as $value) {
+ $isHit = true;
+ }
+ } catch (\Exception $e) {
+ CacheItem::log($this->logger, 'Failed to fetch key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
+ }
+
+ return $f($key, $value, $isHit);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItems(array $keys = [])
+ {
+ if ($this->deferred) {
+ $this->commit();
+ }
+ $ids = [];
+
+ foreach ($keys as $key) {
+ $ids[] = $this->getId($key);
+ }
+ try {
+ $items = $this->doFetch($ids);
+ } catch (\Exception $e) {
+ CacheItem::log($this->logger, 'Failed to fetch items: '.$e->getMessage(), ['keys' => $keys, 'exception' => $e]);
+ $items = [];
+ }
+ $ids = array_combine($ids, $keys);
+
+ return $this->generateItems($items, $ids);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save(CacheItemInterface $item)
+ {
+ if (!$item instanceof CacheItem) {
+ return false;
+ }
+ $this->deferred[$item->getKey()] = $item;
+
+ return $this->commit();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function saveDeferred(CacheItemInterface $item)
+ {
+ if (!$item instanceof CacheItem) {
+ return false;
+ }
+ $this->deferred[$item->getKey()] = $item;
+
+ return true;
+ }
+
+ public function __destruct()
+ {
+ if ($this->deferred) {
+ $this->commit();
+ }
+ }
+
+ private function generateItems($items, &$keys)
+ {
+ $f = $this->createCacheItem;
+
+ try {
+ foreach ($items as $id => $value) {
+ if (!isset($keys[$id])) {
+ $id = key($keys);
+ }
+ $key = $keys[$id];
+ unset($keys[$id]);
+ yield $key => $f($key, $value, true);
+ }
+ } catch (\Exception $e) {
+ CacheItem::log($this->logger, 'Failed to fetch items: '.$e->getMessage(), ['keys' => array_values($keys), 'exception' => $e]);
+ }
+
+ foreach ($keys as $key) {
+ yield $key => $f($key, null, false);
+ }
+ }
+}
diff --git a/vendor/symfony/cache/Traits/AbstractTrait.php b/vendor/symfony/cache/Traits/AbstractTrait.php
index 2553ea75cb..1d6c189c81 100644
--- a/vendor/symfony/cache/Traits/AbstractTrait.php
+++ b/vendor/symfony/cache/Traits/AbstractTrait.php
@@ -94,7 +94,7 @@ trait AbstractTrait
try {
return $this->doHave($id);
} catch (\Exception $e) {
- CacheItem::log($this->logger, 'Failed to check if key "{key}" is cached', ['key' => $key, 'exception' => $e]);
+ CacheItem::log($this->logger, 'Failed to check if key "{key}" is cached: '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
return false;
}
@@ -122,7 +122,7 @@ trait AbstractTrait
try {
return $this->doClear($this->namespace) || $cleared;
} catch (\Exception $e) {
- CacheItem::log($this->logger, 'Failed to clear the cache', ['exception' => $e]);
+ CacheItem::log($this->logger, 'Failed to clear the cache: '.$e->getMessage(), ['exception' => $e]);
return false;
}
@@ -166,7 +166,8 @@ trait AbstractTrait
}
} catch (\Exception $e) {
}
- CacheItem::log($this->logger, 'Failed to delete key "{key}"', ['key' => $key, 'exception' => $e]);
+ $message = 'Failed to delete key "{key}"'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
+ CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e]);
$ok = false;
}
diff --git a/vendor/symfony/cache/Traits/ArrayTrait.php b/vendor/symfony/cache/Traits/ArrayTrait.php
index e585c3d48c..8ae9cad59b 100644
--- a/vendor/symfony/cache/Traits/ArrayTrait.php
+++ b/vendor/symfony/cache/Traits/ArrayTrait.php
@@ -128,7 +128,8 @@ trait ArrayTrait
$serialized = serialize($value);
} catch (\Exception $e) {
$type = \is_object($value) ? \get_class($value) : \gettype($value);
- CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => $key, 'type' => $type, 'exception' => $e]);
+ $message = sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage());
+ CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e]);
return;
}
@@ -150,7 +151,7 @@ trait ArrayTrait
try {
$value = unserialize($value);
} catch (\Exception $e) {
- CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', ['key' => $key, 'exception' => $e]);
+ CacheItem::log($this->logger, 'Failed to unserialize key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
$value = false;
}
if (false === $value) {
diff --git a/vendor/symfony/cache/Traits/ContractsTrait.php b/vendor/symfony/cache/Traits/ContractsTrait.php
index bd7be08dd5..d9514d3965 100644
--- a/vendor/symfony/cache/Traits/ContractsTrait.php
+++ b/vendor/symfony/cache/Traits/ContractsTrait.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Cache\Traits;
+use Psr\Log\LoggerInterface;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
@@ -31,6 +32,7 @@ trait ContractsTrait
}
private $callbackWrapper = [LockRegistry::class, 'compute'];
+ private $computing = [];
/**
* Wraps the callback passed to ->get() in a callable.
@@ -40,7 +42,7 @@ trait ContractsTrait
public function setCallbackWrapper(?callable $callbackWrapper): callable
{
$previousWrapper = $this->callbackWrapper;
- $this->callbackWrapper = $callbackWrapper ?? function (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata) {
+ $this->callbackWrapper = $callbackWrapper ?? function (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger) {
return $callback($item, $save);
};
@@ -68,27 +70,28 @@ trait ContractsTrait
CacheItem::class
);
- return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata) {
+ return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata, $key) {
// don't wrap nor save recursive calls
- if (null === $callbackWrapper = $this->callbackWrapper) {
+ if (isset($this->computing[$key])) {
$value = $callback($item, $save);
$save = false;
return $value;
}
- $this->callbackWrapper = null;
+
+ $this->computing[$key] = $key;
$startTime = microtime(true);
try {
- $value = $callbackWrapper($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) {
+ $value = ($this->callbackWrapper)($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) {
$setMetadata($item, $startTime, $metadata);
- });
+ }, $this->logger ?? null);
$setMetadata($item, $startTime, $metadata);
return $value;
} finally {
- $this->callbackWrapper = $callbackWrapper;
+ unset($this->computing[$key]);
}
- }, $beta, $metadata);
+ }, $beta, $metadata, $this->logger ?? null);
}
}
diff --git a/vendor/symfony/cache/Traits/FilesystemCommonTrait.php b/vendor/symfony/cache/Traits/FilesystemCommonTrait.php
index 3f684acd68..37e1fd1f06 100644
--- a/vendor/symfony/cache/Traits/FilesystemCommonTrait.php
+++ b/vendor/symfony/cache/Traits/FilesystemCommonTrait.php
@@ -101,11 +101,11 @@ trait FilesystemCommonTrait
}
}
- private function getFile($id, $mkdir = false)
+ private function getFile($id, $mkdir = false, string $directory = null)
{
// Use MD5 to favor speed over security, which is not an issue here
$hash = str_replace('/', '-', base64_encode(hash('md5', static::class.$id, true)));
- $dir = $this->directory.strtoupper($hash[0].\DIRECTORY_SEPARATOR.$hash[1].\DIRECTORY_SEPARATOR);
+ $dir = ($directory ?? $this->directory).strtoupper($hash[0].\DIRECTORY_SEPARATOR.$hash[1].\DIRECTORY_SEPARATOR);
if ($mkdir && !file_exists($dir)) {
@mkdir($dir, 0777, true);
diff --git a/vendor/symfony/cache/Traits/RedisTrait.php b/vendor/symfony/cache/Traits/RedisTrait.php
index 350a54360e..b2faca651d 100644
--- a/vendor/symfony/cache/Traits/RedisTrait.php
+++ b/vendor/symfony/cache/Traits/RedisTrait.php
@@ -80,15 +80,19 @@ trait RedisTrait
*/
public static function createConnection($dsn, array $options = [])
{
- if (0 !== strpos($dsn, 'redis:')) {
- throw new InvalidArgumentException(sprintf('Invalid Redis DSN: %s does not start with "redis:".', $dsn));
+ if (0 === strpos($dsn, 'redis:')) {
+ $scheme = 'redis';
+ } elseif (0 === strpos($dsn, 'rediss:')) {
+ $scheme = 'rediss';
+ } else {
+ throw new InvalidArgumentException(sprintf('Invalid Redis DSN: %s does not start with "redis:" or "rediss".', $dsn));
}
if (!\extension_loaded('redis') && !class_exists(\Predis\Client::class)) {
throw new CacheException(sprintf('Cannot find the "redis" extension nor the "predis/predis" package: %s', $dsn));
}
- $params = preg_replace_callback('#^redis:(//)?(?:(?:[^:@]*+:)?([^@]*+)@)?#', function ($m) use (&$auth) {
+ $params = preg_replace_callback('#^'.$scheme.':(//)?(?:(?:[^:@]*+:)?([^@]*+)@)?#', function ($m) use (&$auth) {
if (isset($m[2])) {
$auth = $m[2];
}
@@ -317,33 +321,13 @@ trait RedisTrait
protected function doClear($namespace)
{
$cleared = true;
- $hosts = [$this->redis];
- $evalArgs = [[$namespace], 0];
-
if ($this->redis instanceof \Predis\Client) {
$evalArgs = [0, $namespace];
-
- $connection = $this->redis->getConnection();
- if ($connection instanceof ClusterInterface && $connection instanceof \Traversable) {
- $hosts = [];
- foreach ($connection as $c) {
- $hosts[] = new \Predis\Client($c);
- }
- }
- } elseif ($this->redis instanceof \RedisArray) {
- $hosts = [];
- foreach ($this->redis->_hosts() as $host) {
- $hosts[] = $this->redis->_instance($host);
- }
- } elseif ($this->redis instanceof RedisClusterProxy || $this->redis instanceof \RedisCluster) {
- $hosts = [];
- foreach ($this->redis->_masters() as $host) {
- $hosts[] = $h = new \Redis();
- $h->connect($host[0], $host[1]);
- }
+ } else {
+ $evalArgs = [[$namespace], 0];
}
- foreach ($hosts as $host) {
+ foreach ($this->getHosts() as $host) {
if (!isset($namespace[0])) {
$cleared = $host->flushDb() && $cleared;
continue;
@@ -475,4 +459,31 @@ trait RedisTrait
yield $id => $results[$k];
}
}
+
+ private function getHosts(): array
+ {
+ $hosts = [$this->redis];
+ if ($this->redis instanceof \Predis\Client) {
+ $connection = $this->redis->getConnection();
+ if ($connection instanceof ClusterInterface && $connection instanceof \Traversable) {
+ $hosts = [];
+ foreach ($connection as $c) {
+ $hosts[] = new \Predis\Client($c);
+ }
+ }
+ } elseif ($this->redis instanceof \RedisArray) {
+ $hosts = [];
+ foreach ($this->redis->_hosts() as $host) {
+ $hosts[] = $this->redis->_instance($host);
+ }
+ } elseif ($this->redis instanceof RedisClusterProxy || $this->redis instanceof \RedisCluster) {
+ $hosts = [];
+ foreach ($this->redis->_masters() as $host) {
+ $hosts[] = $h = new \Redis();
+ $h->connect($host[0], $host[1]);
+ }
+ }
+
+ return $hosts;
+ }
}