Skip to content

Commit 5d68adb

Browse files
committed
add (pdo|chain) cache (adapter|simple) prune method
1 parent f0d0c5f commit 5d68adb

16 files changed

+331
-8
lines changed

src/Symfony/Component/Cache/Adapter/ChainAdapter.php

+13-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
use Psr\Cache\CacheItemPoolInterface;
1616
use Symfony\Component\Cache\CacheItem;
1717
use Symfony\Component\Cache\Exception\InvalidArgumentException;
18+
use Symfony\Component\Cache\PruneableInterface;
19+
use Symfony\Component\Cache\Traits\ChainTrait;
1820

1921
/**
2022
* Chains several adapters together.
@@ -24,8 +26,10 @@
2426
*
2527
* @author Kévin Dunglas <dunglas@gmail.com>
2628
*/
27-
class ChainAdapter implements AdapterInterface
29+
class ChainAdapter implements AdapterInterface, PruneableInterface
2830
{
31+
use ChainTrait;
32+
2933
private $adapters = array();
3034
private $adapterCount;
3135
private $saveUp;
@@ -231,4 +235,12 @@ public function commit()
231235

232236
return $committed;
233237
}
238+
239+
/**
240+
* {@inheritdoc}
241+
*/
242+
public function prune()
243+
{
244+
return $this->doPrune($this->adapters);
245+
}
234246
}

src/Symfony/Component/Cache/Adapter/PdoAdapter.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111

1212
namespace Symfony\Component\Cache\Adapter;
1313

14+
use Symfony\Component\Cache\PruneableInterface;
1415
use Symfony\Component\Cache\Traits\PdoTrait;
1516

16-
class PdoAdapter extends AbstractAdapter
17+
class PdoAdapter extends AbstractAdapter implements PruneableInterface
1718
{
1819
use PdoTrait;
1920

src/Symfony/Component/Cache/CHANGELOG.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ CHANGELOG
55
-----
66

77
* added PruneableInterface so PSR-6 or PSR-16 cache implementations can declare support for manual stale cache pruning
8-
* added FilesystemTrait::prune() and PhpFilesTrait::prune() implementations
9-
* now FilesystemAdapter, PhpFilesAdapter, FilesystemCache, and PhpFilesCache implement PruneableInterface and support
10-
manual stale cache pruning
8+
* added prune logic to FilesystemTrait, PhpFilesTrait, PdoTrait, and ChainTrait
9+
* now FilesystemAdapter, PhpFilesAdapter, FilesystemCache, PhpFilesCache, PdoAdapter, PdoCache, ChainAdapter, and
10+
ChainCache implement PruneableInterface and support manual stale cache pruning
1111

1212
3.3.0
1313
-----

src/Symfony/Component/Cache/Simple/ChainCache.php

+13-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
use Psr\SimpleCache\CacheInterface;
1515
use Symfony\Component\Cache\Exception\InvalidArgumentException;
16+
use Symfony\Component\Cache\PruneableInterface;
17+
use Symfony\Component\Cache\Traits\ChainTrait;
1618

1719
/**
1820
* Chains several caches together.
@@ -22,8 +24,10 @@
2224
*
2325
* @author Nicolas Grekas <p@tchwork.com>
2426
*/
25-
class ChainCache implements CacheInterface
27+
class ChainCache implements CacheInterface, PruneableInterface
2628
{
29+
use ChainTrait;
30+
2731
private $miss;
2832
private $caches = array();
2933
private $defaultLifetime;
@@ -219,4 +223,12 @@ public function setMultiple($values, $ttl = null)
219223

220224
return $saved;
221225
}
226+
227+
/**
228+
* {@inheritdoc}
229+
*/
230+
public function prune()
231+
{
232+
return $this->doPrune($this->caches);
233+
}
222234
}

src/Symfony/Component/Cache/Simple/PdoCache.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111

1212
namespace Symfony\Component\Cache\Simple;
1313

14+
use Symfony\Component\Cache\PruneableInterface;
1415
use Symfony\Component\Cache\Traits\PdoTrait;
1516

16-
class PdoCache extends AbstractCache
17+
class PdoCache extends AbstractCache implements PruneableInterface
1718
{
1819
use PdoTrait;
1920

src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php

+15
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Cache\Tests\Adapter;
1313

1414
use Cache\IntegrationTests\CachePoolTest;
15+
use Psr\Cache\CacheItemPoolInterface;
1516
use Symfony\Component\Cache\PruneableInterface;
1617

1718
abstract class AdapterTestCase extends CachePoolTest
@@ -83,6 +84,7 @@ public function testPrune()
8384
$this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.');
8485
}
8586

87+
/** @var PruneableInterface|CacheItemPoolInterface $cache */
8688
$cache = $this->createCachePool();
8789

8890
$doSet = function ($name, $value, \DateInterval $expiresAfter = null) use ($cache) {
@@ -96,6 +98,19 @@ public function testPrune()
9698
$cache->save($item);
9799
};
98100

101+
102+
$doSet('foo', 'foo-val', new \DateInterval('PT05S'));
103+
$doSet('bar', 'bar-val', new \DateInterval('PT10S'));
104+
$doSet('baz', 'baz-val', new \DateInterval('PT15S'));
105+
$doSet('qux', 'qux-val', new \DateInterval('PT20S'));
106+
107+
sleep(30);
108+
$cache->prune();
109+
$this->assertTrue($this->isPruned($cache, 'foo'));
110+
$this->assertTrue($this->isPruned($cache, 'bar'));
111+
$this->assertTrue($this->isPruned($cache, 'baz'));
112+
$this->assertTrue($this->isPruned($cache, 'qux'));
113+
99114
$doSet('foo', 'foo-val');
100115
$doSet('bar', 'bar-val', new \DateInterval('PT20S'));
101116
$doSet('baz', 'baz-val', new \DateInterval('PT40S'));

src/Symfony/Component/Cache/Tests/Adapter/ChainAdapterTest.php

+71
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111

1212
namespace Symfony\Component\Cache\Tests\Adapter;
1313

14+
use Symfony\Component\Cache\Adapter\AdapterInterface;
1415
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
1516
use Symfony\Component\Cache\Adapter\ArrayAdapter;
1617
use Symfony\Component\Cache\Adapter\ChainAdapter;
18+
use Symfony\Component\Cache\PruneableInterface;
1719
use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter;
1820

1921
/**
@@ -44,4 +46,73 @@ public function testInvalidAdapterException()
4446
{
4547
new ChainAdapter(array(new \stdClass()));
4648
}
49+
50+
public function testPrune()
51+
{
52+
if (isset($this->skippedTests[__FUNCTION__])) {
53+
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
54+
}
55+
56+
$cache = new ChainAdapter(array(
57+
$this->getPruneableMock(),
58+
$this->getNonPruneableMock(),
59+
$this->getPruneableMock(),
60+
));
61+
$this->assertTrue($cache->prune());
62+
63+
$cache = new ChainAdapter(array(
64+
$this->getPruneableMock(),
65+
$this->getFailingPruneableMock(),
66+
$this->getPruneableMock(),
67+
));
68+
$this->assertFalse($cache->prune());
69+
}
70+
71+
/**
72+
* @return \PHPUnit_Framework_MockObject_MockObject|PruneableCacheInterface
73+
*/
74+
private function getPruneableMock()
75+
{
76+
$pruneable = $this
77+
->getMockBuilder(PruneableCacheInterface::class)
78+
->getMock();
79+
80+
$pruneable
81+
->expects($this->atLeastOnce())
82+
->method('prune')
83+
->will($this->returnValue(true));
84+
85+
return $pruneable;
86+
}
87+
88+
/**
89+
* @return \PHPUnit_Framework_MockObject_MockObject|PruneableCacheInterface
90+
*/
91+
private function getFailingPruneableMock()
92+
{
93+
$pruneable = $this
94+
->getMockBuilder(PruneableCacheInterface::class)
95+
->getMock();
96+
97+
$pruneable
98+
->expects($this->atLeastOnce())
99+
->method('prune')
100+
->will($this->returnValue(false));
101+
102+
return $pruneable;
103+
}
104+
105+
/**
106+
* @return \PHPUnit_Framework_MockObject_MockObject|AdapterInterface
107+
*/
108+
private function getNonPruneableMock()
109+
{
110+
return $this
111+
->getMockBuilder(AdapterInterface::class)
112+
->getMock();
113+
}
114+
}
115+
116+
interface PruneableCacheInterface extends PruneableInterface, AdapterInterface
117+
{
47118
}

src/Symfony/Component/Cache/Tests/Adapter/PdoAdapterTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@
1212
namespace Symfony\Component\Cache\Tests\Adapter;
1313

1414
use Symfony\Component\Cache\Adapter\PdoAdapter;
15+
use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
1516

1617
/**
1718
* @group time-sensitive
1819
*/
1920
class PdoAdapterTest extends AdapterTestCase
2021
{
22+
use PdoPruneableTrait;
23+
2124
protected static $dbFile;
2225

2326
public static function setupBeforeClass()

src/Symfony/Component/Cache/Tests/Adapter/PdoDbalAdapterTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@
1313

1414
use Doctrine\DBAL\DriverManager;
1515
use Symfony\Component\Cache\Adapter\PdoAdapter;
16+
use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
1617

1718
/**
1819
* @group time-sensitive
1920
*/
2021
class PdoDbalAdapterTest extends AdapterTestCase
2122
{
23+
use PdoPruneableTrait;
24+
2225
protected static $dbFile;
2326

2427
public static function setupBeforeClass()

src/Symfony/Component/Cache/Tests/Simple/CacheTestCase.php

+14
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Cache\Tests\Simple;
1313

1414
use Cache\IntegrationTests\SimpleCacheTest;
15+
use Psr\SimpleCache\CacheInterface;
1516
use Symfony\Component\Cache\PruneableInterface;
1617

1718
abstract class CacheTestCase extends SimpleCacheTest
@@ -80,8 +81,21 @@ public function testPrune()
8081
$this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.');
8182
}
8283

84+
/** @var PruneableInterface|CacheInterface $cache */
8385
$cache = $this->createSimpleCache();
8486

87+
$cache->set('foo', 'foo-val', new \DateInterval('PT05S'));
88+
$cache->set('bar', 'bar-val', new \DateInterval('PT10S'));
89+
$cache->set('baz', 'baz-val', new \DateInterval('PT15S'));
90+
$cache->set('qux', 'qux-val', new \DateInterval('PT20S'));
91+
92+
sleep(30);
93+
$cache->prune();
94+
$this->assertTrue($this->isPruned($cache, 'foo'));
95+
$this->assertTrue($this->isPruned($cache, 'bar'));
96+
$this->assertTrue($this->isPruned($cache, 'baz'));
97+
$this->assertTrue($this->isPruned($cache, 'qux'));
98+
8599
$cache->set('foo', 'foo-val');
86100
$cache->set('bar', 'bar-val', new \DateInterval('PT20S'));
87101
$cache->set('baz', 'baz-val', new \DateInterval('PT40S'));

src/Symfony/Component/Cache/Tests/Simple/ChainCacheTest.php

+72-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Cache\Tests\Simple;
1313

14+
use Psr\SimpleCache\CacheInterface;
15+
use Symfony\Component\Cache\PruneableInterface;
1416
use Symfony\Component\Cache\Simple\ArrayCache;
1517
use Symfony\Component\Cache\Simple\ChainCache;
1618
use Symfony\Component\Cache\Simple\FilesystemCache;
@@ -40,6 +42,75 @@ public function testEmptyCachesException()
4042
*/
4143
public function testInvalidCacheException()
4244
{
43-
new Chaincache(array(new \stdClass()));
45+
new ChainCache(array(new \stdClass()));
4446
}
47+
48+
public function testPrune()
49+
{
50+
if (isset($this->skippedTests[__FUNCTION__])) {
51+
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
52+
}
53+
54+
$cache = new ChainCache(array(
55+
$this->getPruneableMock(),
56+
$this->getNonPruneableMock(),
57+
$this->getPruneableMock(),
58+
));
59+
$this->assertTrue($cache->prune());
60+
61+
$cache = new ChainCache(array(
62+
$this->getPruneableMock(),
63+
$this->getFailingPruneableMock(),
64+
$this->getPruneableMock(),
65+
));
66+
$this->assertFalse($cache->prune());
67+
}
68+
69+
/**
70+
* @return \PHPUnit_Framework_MockObject_MockObject|PruneableCacheInterface
71+
*/
72+
private function getPruneableMock()
73+
{
74+
$pruneable = $this
75+
->getMockBuilder(PruneableCacheInterface::class)
76+
->getMock();
77+
78+
$pruneable
79+
->expects($this->atLeastOnce())
80+
->method('prune')
81+
->will($this->returnValue(true));
82+
83+
return $pruneable;
84+
}
85+
86+
/**
87+
* @return \PHPUnit_Framework_MockObject_MockObject|PruneableCacheInterface
88+
*/
89+
private function getFailingPruneableMock()
90+
{
91+
$pruneable = $this
92+
->getMockBuilder(PruneableCacheInterface::class)
93+
->getMock();
94+
95+
$pruneable
96+
->expects($this->atLeastOnce())
97+
->method('prune')
98+
->will($this->returnValue(false));
99+
100+
return $pruneable;
101+
}
102+
103+
/**
104+
* @return \PHPUnit_Framework_MockObject_MockObject|CacheInterface
105+
*/
106+
private function getNonPruneableMock()
107+
{
108+
return $this
109+
->getMockBuilder(CacheInterface::class)
110+
->getMock();
111+
}
112+
}
113+
114+
interface PruneableCacheInterface extends PruneableInterface, CacheInterface
115+
{
45116
}

src/Symfony/Component/Cache/Tests/Simple/PdoCacheTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@
1212
namespace Symfony\Component\Cache\Tests\Simple;
1313

1414
use Symfony\Component\Cache\Simple\PdoCache;
15+
use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
1516

1617
/**
1718
* @group time-sensitive
1819
*/
1920
class PdoCacheTest extends CacheTestCase
2021
{
22+
use PdoPruneableTrait;
23+
2124
protected static $dbFile;
2225

2326
public static function setupBeforeClass()

0 commit comments

Comments
 (0)