Skip to content

Commit 9d11155

Browse files
committed
Merge branch 'hotfix/2.0.3'
2 parents 3da8b49 + 77ae7f3 commit 9d11155

File tree

2 files changed

+80
-3
lines changed

2 files changed

+80
-3
lines changed

src/Psr6Store.php

+9-2
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public function __construct(array $options = [])
135135

136136
$resolver->setDefault('lock_factory', function (Options $options) {
137137
if (!isset($options['cache_directory'])) {
138-
throw new MissingOptionsException('The cache_directory option is required unless you set the cache explicitly');
138+
throw new MissingOptionsException('The cache_directory option is required unless you set the lock_factory explicitly as by default locks are also stored in the configured cache_directory.');
139139
}
140140

141141
return new Factory(
@@ -395,7 +395,14 @@ public function prune()
395395
return;
396396
}
397397

398-
$this->cache->prune();
398+
// Make sure we do not have multiple pruning processes running
399+
$lock = $this->lockFactory->createLock('prune-lock');
400+
401+
if ($lock->acquire()) {
402+
$this->cache->prune();
403+
404+
$lock->release();
405+
}
399406
}
400407

401408
/**

tests/Psr6StoreTest.php

+71-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ protected function tearDown()
4444
$this->store->cleanup();
4545
}
4646

47+
public function testCustomCacheWithoutLockFactory()
48+
{
49+
$this->expectException(MissingOptionsException::class);
50+
$this->expectExceptionMessage('The cache_directory option is required unless you set the lock_factory explicitly as by default locks are also stored in the configured cache_directory.');
51+
52+
$cache = $this->createMock(TagAwareAdapterInterface::class);
53+
54+
new Psr6Store([
55+
'cache' => $cache,
56+
]);
57+
}
58+
4759
public function testCustomCacheAndLockFactory()
4860
{
4961
$cache = $this->createMock(TagAwareAdapterInterface::class);
@@ -494,10 +506,27 @@ public function testAutoPruneExpiredEntries()
494506
->expects($this->exactly(3))
495507
->method('prune');
496508

509+
$lock = $this->createMock(LockInterface::class);
510+
$lock
511+
->expects($this->exactly(3))
512+
->method('acquire')
513+
->willReturn(true);
514+
$lock
515+
->expects($this->exactly(3))
516+
->method('release')
517+
->willReturn(true);
518+
519+
$lockFactory = $this->createMock(Factory::class);
520+
$lockFactory
521+
->expects($this->any())
522+
->method('createLock')
523+
->with('prune-lock')
524+
->willReturn($lock);
525+
497526
$store = new Psr6Store([
498-
'cache_directory' => sys_get_temp_dir(),
499527
'cache' => $cache,
500528
'prune_threshold' => 5,
529+
'lock_factory' => $lockFactory,
501530
]);
502531

503532
foreach (range(1, 21) as $entry) {
@@ -538,6 +567,47 @@ public function testAutoPruneIsSkippedIfThresholdDisabled()
538567
$store->cleanup();
539568
}
540569

570+
public function testAutoPruneIsSkippedIfPruningIsAlreadyInProgress()
571+
{
572+
$innerCache = new ArrayAdapter();
573+
$cache = $this->getMockBuilder(TagAwareAdapter::class)
574+
->setConstructorArgs([$innerCache])
575+
->setMethods(['prune'])
576+
->getMock();
577+
578+
$cache
579+
->expects($this->never())
580+
->method('prune');
581+
582+
$lock = $this->createMock(LockInterface::class);
583+
$lock
584+
->expects($this->exactly(3))
585+
->method('acquire')
586+
->willReturn(false);
587+
588+
$lockFactory = $this->createMock(Factory::class);
589+
$lockFactory
590+
->expects($this->any())
591+
->method('createLock')
592+
->with('prune-lock')
593+
->willReturn($lock);
594+
595+
$store = new Psr6Store([
596+
'cache' => $cache,
597+
'prune_threshold' => 5,
598+
'lock_factory' => $lockFactory,
599+
]);
600+
601+
foreach (range(1, 21) as $entry) {
602+
$request = Request::create('https://foobar.com/'.$entry);
603+
$response = new Response('hello world', 200);
604+
605+
$store->write($request, $response);
606+
}
607+
608+
$store->cleanup();
609+
}
610+
541611
public function testItFailsWithoutCacheDirectoryForCache()
542612
{
543613
$this->expectException(MissingOptionsException::class);

0 commit comments

Comments
 (0)