Skip to content

Commit 0c167f9

Browse files
authored
Merge pull request #332 from Geolim4/final
Implemented #331
2 parents 2213126 + 9f2d565 commit 0c167f9

File tree

7 files changed

+163
-3
lines changed

7 files changed

+163
-3
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ script:
3030
- php -f tests/NewCacheInstance.test.php
3131
- php -f tests/Psr6InterfaceImplements.test.php
3232
- php -f tests/AbstractProxy.test.php
33+
- php -f tests/AttachingDetachingMethods.test.php

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ phpFastCache offers you a lot of useful APIs:
105105
- appendItemsByTags(array $tagNames, $data) // Append items by some tags
106106
- prependItemsByTag($tagName, $data) // Prepend items by a tag
107107
- prependItemsByTags(array $tagNames, $data) // Prepend items by some tags
108+
- detachItem($item) // Detach an item from the pool
109+
- detachAllItems($item) // Detach all items from the pool
110+
- attachItem($item) // (Re-)attach an item to the pool
111+
- isAttached($item) // Verify if an item is (still) attached
108112

109113
Also support Multiple calls, Tagging, Setup Folder for caching. Look at our examples folders.
110114

src/phpFastCache/Api.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121
class Api
2222
{
23-
protected static $version = '1.1.1';
23+
protected static $version = '1.1.2';
2424

2525
/**
2626
* This method will returns the current
@@ -45,6 +45,13 @@ public static function getVersion()
4545
public static function getChangelog()
4646
{
4747
return <<<CHANGELOG
48+
- 1.1.2
49+
-- Implemented [de|a]ttaching methods to improve memory management
50+
ExtendedCacheItemPoolInterface::detachItem()
51+
ExtendedCacheItemPoolInterface::detachAllItems()
52+
ExtendedCacheItemPoolInterface::attachItem()
53+
ExtendedCacheItemPoolInterface::isAttached()
54+
4855
- 1.1.1
4956
-- Implemented JsonSerializable interface to ExtendedCacheItemInterface
5057

src/phpFastCache/Cache/ExtendedCacheItemPoolInterface.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public function setItem(CacheItemInterface $item);
105105
* True if the pool was successfully cleared. False if there was an error.
106106
*/
107107
public function clean();
108-
108+
109109
/**
110110
* @return driverStatistic
111111
*/
@@ -325,4 +325,33 @@ public function prependItemsByTag($tagName, $data);
325325
* True if the item was successfully prepended. False if there was an error.
326326
*/
327327
public function prependItemsByTags(array $tagNames, $data);
328+
329+
/**
330+
* @param \Psr\Cache\CacheItemInterface $item
331+
* @return void
332+
*/
333+
public function detachItem(CacheItemInterface $item);
334+
335+
/**
336+
* @return void
337+
*/
338+
public function detachAllItems();
339+
340+
/**
341+
* @param \Psr\Cache\CacheItemInterface $item
342+
* @return void
343+
* @throws \LogicException
344+
*/
345+
public function attachItem(CacheItemInterface $item);
346+
347+
/**
348+
* Returns true if the item exists, is attached and the Spl Hash matches
349+
* Returns false if the item exists, is attached and the Spl Hash mismatches
350+
* Returns null if the item does not exists
351+
*
352+
* @param \Psr\Cache\CacheItemInterface $item
353+
* @return bool|null
354+
* @throws \LogicException
355+
*/
356+
public function isAttached(CacheItemInterface $item);
328357
}

src/phpFastCache/Core/ExtendedCacheItemPoolTrait.php

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public function getItemsByTag($tagName)
7171
* Therefore we pass a filter callback
7272
* to remove the expired Item(s) provided by
7373
* the item keys passed through getItems()
74-
*
74+
*
7575
* #headache
7676
*/
7777
return array_filter($this->getItems(array_unique(array_keys($items))), function(ExtendedCacheItemInterface $item){
@@ -296,6 +296,43 @@ public function prependItemsByTags(array $tagNames, $data)
296296
}
297297

298298
/**
299+
* @param \Psr\Cache\CacheItemInterface $item
300+
* @return void
301+
*/
302+
public function detachItem(CacheItemInterface $item)
303+
{
304+
if(isset($this->itemInstances[$item->getKey()])){
305+
$this->deregisterItem($item);
306+
}
307+
}
308+
309+
/**
310+
* @return void
311+
*/
312+
public function detachAllItems()
313+
{
314+
foreach ($this->itemInstances as $item) {
315+
$this->detachItem($item);
316+
}
317+
}
318+
319+
/**
320+
* @param \Psr\Cache\CacheItemInterface $item
321+
* @return void
322+
* @throws \LogicException
323+
*/
324+
public function attachItem(CacheItemInterface $item)
325+
{
326+
if(isset($this->itemInstances[$item->getKey()]) && spl_object_hash($item) !== spl_object_hash($this->itemInstances[ $item->getKey() ])){
327+
throw new \LogicException('The item already exists and cannot be overwritten because the Spl object hash mismatches ! You probably tried to re-attach a detached item which has been already retrieved from cache.');
328+
}else{
329+
$this->itemInstances[$item->getKey()] = $item;
330+
}
331+
}
332+
333+
334+
/**
335+
* @internal This method de-register an item from $this->itemInstances
299336
* @param CacheItemInterface|string $item
300337
* @throws \InvalidArgumentException
301338
*/
@@ -313,4 +350,21 @@ protected function deregisterItem($item)
313350
gc_collect_cycles();
314351
}
315352
}
353+
354+
/**
355+
* Returns true if the item exists, is attached and the Spl Hash matches
356+
* Returns false if the item exists, is attached and the Spl Hash mismatches
357+
* Returns null if the item does not exists
358+
*
359+
* @param \Psr\Cache\CacheItemInterface $item
360+
* @return bool|null
361+
* @throws \LogicException
362+
*/
363+
public function isAttached(CacheItemInterface $item)
364+
{
365+
if(isset($this->itemInstances[$item->getKey()])){
366+
return spl_object_hash($item) === spl_object_hash($this->itemInstances[ $item->getKey() ]);
367+
}
368+
return null;
369+
}
316370
}

src/phpFastCache/Core/StandardPsr6StructureTrait.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ public function deleteItems(array $keys)
182182
* @param \Psr\Cache\CacheItemInterface $item
183183
* @return mixed
184184
* @throws \InvalidArgumentException
185+
* @throws \RuntimeException
185186
*/
186187
public function save(CacheItemInterface $item)
187188
{
@@ -190,7 +191,11 @@ public function save(CacheItemInterface $item)
190191
*/
191192
if (!array_key_exists($item->getKey(), $this->itemInstances)) {
192193
$this->itemInstances[ $item->getKey() ] = $item;
194+
} else if(spl_object_hash($item) !== spl_object_hash($this->itemInstances[ $item->getKey() ])){
195+
throw new \RuntimeException('Spl object hash mismatches ! You probably tried to save a detached item which has been already retrieved from cache.');
193196
}
197+
198+
194199
if ($this->driverWrite($item) && $this->driverWriteTags($item)) {
195200
$item->setHit(true);
196201
CacheManager::$WriteHits++;
@@ -204,11 +209,14 @@ public function save(CacheItemInterface $item)
204209
/**
205210
* @param \Psr\Cache\CacheItemInterface $item
206211
* @return \Psr\Cache\CacheItemInterface
212+
* @throws \RuntimeException
207213
*/
208214
public function saveDeferred(CacheItemInterface $item)
209215
{
210216
if (!array_key_exists($item->getKey(), $this->itemInstances)) {
211217
$this->itemInstances[ $item->getKey() ] = $item;
218+
}else if(spl_object_hash($item) !== spl_object_hash($this->itemInstances[ $item->getKey() ])){
219+
throw new \RuntimeException('Spl object hash mismatches ! You probably tried to save a detached item which has been already retrieved from cache.');
212220
}
213221

214222
return $this->deferredList[ $item->getKey() ] = $item;
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
/**
4+
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
5+
* @author Georges.L (Geolim4) <contact@geolim4.com>
6+
*/
7+
8+
use phpFastCache\CacheManager;
9+
use phpFastCache\Core\Pool\ExtendedCacheItemPoolInterface;
10+
use Psr\Cache\CacheItemPoolInterface;
11+
12+
13+
chdir(__DIR__);
14+
require_once __DIR__ . '/../vendor/autoload.php';
15+
16+
$status = 0;
17+
echo "Testing [a|de]ttaching methods\n";
18+
19+
/**
20+
* Testing memcached as it is declared in .travis.yml
21+
*/
22+
$driverInstance = CacheManager::getInstance('Files');
23+
24+
if (!is_object($driverInstance)) {
25+
echo '[FAIL] CacheManager::getInstance() returned an invalid variable type:' . gettype($driverInstance) . "\n";
26+
$status = 1;
27+
}else if(!($driverInstance instanceof CacheItemPoolInterface)){
28+
echo '[FAIL] CacheManager::getInstance() returned an invalid class:' . get_class($driverInstance) . "\n";
29+
$status = 1;
30+
}else{
31+
$key = 'test_attaching_detaching';
32+
33+
$itemDetached = $driverInstance->getItem($key);
34+
$driverInstance->detachItem($itemDetached);
35+
$itemAttached = $driverInstance->getItem($key);
36+
37+
if(!$driverInstance->isAttached($itemDetached))
38+
{
39+
echo '[PASS] ExtendedCacheItemPoolInterface::isAttached() identified $itemDetached as being detached.' . "\n";
40+
}
41+
else
42+
{
43+
echo '[FAIL] ExtendedCacheItemPoolInterface::isAttached() failed to identify $itemDetached as to be detached.' . "\n";
44+
$status = 1;
45+
}
46+
47+
try{
48+
$driverInstance->attachItem($itemDetached);
49+
echo '[FAIL] ExtendedCacheItemPoolInterface::attachItem() attached $itemDetached without trowing an error.' . "\n";
50+
$status = 1;
51+
}catch(\LogicException $e){
52+
echo '[PASS] ExtendedCacheItemPoolInterface::attachItem() failed to attach $itemDetached by trowing a LogicException exception.' . "\n";
53+
}
54+
55+
}
56+
57+
exit($status);

0 commit comments

Comments
 (0)