Skip to content

Commit

Permalink
feature #30370 [Cache] Add optimized FileSystem & Redis TagAware Adap…
Browse files Browse the repository at this point in the history
…ters (andrerom)

This PR was merged into the 4.3-dev branch.

Discussion
----------

[Cache] Add optimized FileSystem & Redis TagAware Adapters

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes _TODO: src/**/CHANGELOG.md_
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #28250
| License       | MIT
| Doc PR        | symfony/symfony-docs#... TODO

Reduces cache lookups by 50% when using TagAware, by changing logic of how tag information is stored to avoid having to look it up on getItem(s) calls.

For Filesystem symlinks are used, for Redis "Set" datatype is used.

Commits
-------

3278cb1 [Cache] Add optimized FileSystem & Redis TagAware Adapters
  • Loading branch information
fabpot committed Apr 24, 2019
2 parents a7d2019 + 3278cb1 commit fba11b4
Show file tree
Hide file tree
Showing 21 changed files with 1,269 additions and 256 deletions.
7 changes: 4 additions & 3 deletions phpunit.xml.dist
Expand Up @@ -71,9 +71,10 @@
<element key="1"><string>Doctrine\Common\Cache</string></element>
<element key="2"><string>Symfony\Component\Cache</string></element>
<element key="3"><string>Symfony\Component\Cache\Tests\Fixtures</string></element>
<element key="4"><string>Symfony\Component\Cache\Traits</string></element>
<element key="5"><string>Symfony\Component\Console</string></element>
<element key="6"><string>Symfony\Component\HttpFoundation</string></element>
<element key="4"><string>Symfony\Component\Cache\Tests\Traits</string></element>
<element key="5"><string>Symfony\Component\Cache\Traits</string></element>
<element key="6"><string>Symfony\Component\Console</string></element>
<element key="7"><string>Symfony\Component\HttpFoundation</string></element>
</array>
</element>
</array>
Expand Down
112 changes: 2 additions & 110 deletions src/Symfony/Component/Cache/Adapter/AbstractAdapter.php
Expand Up @@ -11,14 +11,13 @@

namespace Symfony\Component\Cache\Adapter;

use Psr\Cache\CacheItemInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\AbstractTrait;
use Symfony\Component\Cache\Traits\AbstractAdapterTrait;
use Symfony\Component\Cache\Traits\ContractsTrait;
use Symfony\Contracts\Cache\CacheInterface;

Expand All @@ -27,15 +26,12 @@
*/
abstract class AbstractAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface
{
use AbstractTrait;
use AbstractAdapterTrait;
use ContractsTrait;

private static $apcuSupported;
private static $phpFilesSupported;

private $createCacheItem;
private $mergeByLifetime;

protected function __construct(string $namespace = '', int $defaultLifetime = 0)
{
$this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':';
Expand Down Expand Up @@ -142,81 +138,6 @@ public static function createConnection($dsn, array $options = [])
throw new InvalidArgumentException(sprintf('Unsupported DSN: %s.', $dsn));
}

/**
* {@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}"', ['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 requested items', ['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;
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -271,33 +192,4 @@ public function commit()

return $ok;
}

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 requested items', ['keys' => array_values($keys), 'exception' => $e]);
}

foreach ($keys as $key) {
yield $key => $f($key, null, false);
}
}
}

0 comments on commit fba11b4

Please sign in to comment.