Skip to content

Commit

Permalink
bug #38635 [Cache] Use correct expiry in ChainAdapter (Nyholm)
Browse files Browse the repository at this point in the history
This PR was squashed before being merged into the 4.4 branch.

Discussion
----------

[Cache] Use correct expiry in ChainAdapter

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #38632
| License       | MIT
| Doc PR        | n/a

When we are syncing the chain, Let's use expiry if we have it. If not, fallback to defaultLifetime.

TODO:
- [x] Add tests

Commits
-------

17e0167 [Cache] Use correct expiry in ChainAdapter
  • Loading branch information
nicolas-grekas committed Oct 21, 2020
2 parents 19637c5 + 17e0167 commit 5a4be68
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/Symfony/Component/Cache/Adapter/ChainAdapter.php
Expand Up @@ -73,7 +73,9 @@ static function ($sourceItem, $item, $sourceMetadata = null) use ($defaultLifeti
$item->isHit = $sourceItem->isHit;
$item->metadata = $item->newMetadata = $sourceItem->metadata = $sourceMetadata;

if (0 < $defaultLifetime) {
if (isset($item->metadata[CacheItem::METADATA_EXPIRY])) {
$item->expiresAt(\DateTime::createFromFormat('U.u', $item->metadata[CacheItem::METADATA_EXPIRY]));
} elseif (0 < $defaultLifetime) {
$item->expiresAfter($defaultLifetime);
}

Expand Down
49 changes: 49 additions & 0 deletions src/Symfony/Component/Cache/Tests/Adapter/ChainAdapterTest.php
Expand Up @@ -16,8 +16,10 @@
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\ChainAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter;
use Symfony\Component\Cache\Tests\Fixtures\PrunableAdapter;
use Symfony\Contracts\Cache\ItemInterface;

/**
* @author Kévin Dunglas <dunglas@gmail.com>
Expand All @@ -34,6 +36,11 @@ public function createCachePool(int $defaultLifetime = 0, string $testMethod = n
return new ChainAdapter([new ArrayAdapter($defaultLifetime), new ExternalAdapter($defaultLifetime), new FilesystemAdapter('', $defaultLifetime)], $defaultLifetime);
}

public static function tearDownAfterClass(): void
{
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
}

public function testEmptyAdaptersException()
{
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
Expand Down Expand Up @@ -187,6 +194,48 @@ public function testMultipleCachesExpirationWhenCommonTtlIsSet()
$this->assertFalse($item->isHit());
}

public function testExpirationOnAllAdapters()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}

$itemValidator = function (CacheItem $item) {
$refl = new \ReflectionObject($item);
$propExpiry = $refl->getProperty('expiry');
$propExpiry->setAccessible(true);
$expiry = $propExpiry->getValue($item);
$this->assertGreaterThan(10, $expiry - time(), 'Item should be saved with the given ttl, not the default for the adapter.');

return true;
};

$adapter1 = $this->getMockBuilder(FilesystemAdapter::class)
->setConstructorArgs(['', 2])
->setMethods(['save'])
->getMock();
$adapter1->expects($this->once())
->method('save')
->with($this->callback($itemValidator))
->willReturn(true);

$adapter2 = $this->getMockBuilder(FilesystemAdapter::class)
->setConstructorArgs(['', 4])
->setMethods(['save'])
->getMock();
$adapter2->expects($this->once())
->method('save')
->with($this->callback($itemValidator))
->willReturn(true);

$cache = new ChainAdapter([$adapter1, $adapter2], 6);
$cache->get('test_key', function (ItemInterface $item) {
$item->expiresAfter(15);

return 'chain';
});
}

private function getPruneableMock(): AdapterInterface
{
$pruneable = $this->createMock(PrunableAdapter::class);
Expand Down

0 comments on commit 5a4be68

Please sign in to comment.