From 0aa204befdf650392a22d14f2a6735fc76d26ece Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Fri, 26 May 2017 02:01:06 -0300 Subject: [PATCH 01/16] Starting implementing PSR-16 --- composer.json | 3 +- src/CacheAvailabilityInterface.php | 13 ++++++ src/CacheEngineInterface.php | 55 ---------------------- src/CacheLockInterface.php | 24 ++++++++++ src/Engine/ArrayCacheEngine.php | 73 ++++++++++++------------------ src/Engine/BaseCacheEngine.php | 31 +++++++++++++ src/Engine/NoCacheEngine.php | 56 ++++++++++++++--------- src/{Psr => Psr6}/CacheItem.php | 8 +--- src/{Psr => Psr6}/CachePool.php | 11 +++-- tests/CachePoolTest.php | 2 +- 10 files changed, 141 insertions(+), 135 deletions(-) create mode 100644 src/CacheAvailabilityInterface.php delete mode 100644 src/CacheEngineInterface.php create mode 100644 src/CacheLockInterface.php create mode 100644 src/Engine/BaseCacheEngine.php rename src/{Psr => Psr6}/CacheItem.php (95%) rename src/{Psr => Psr6}/CachePool.php (94%) diff --git a/composer.json b/composer.json index b77187a..9ce1306 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ "require": { "php": ">=5.4.0", "psr/cache": "1.0.*", - "psr/log": "1.0.2" + "psr/log": "1.0.2", + "psr/simple-cache": "1.0.*" }, "suggest": { "ext-memcached": "*" diff --git a/src/CacheAvailabilityInterface.php b/src/CacheAvailabilityInterface.php new file mode 100644 index 0000000..9e66d23 --- /dev/null +++ b/src/CacheAvailabilityInterface.php @@ -0,0 +1,13 @@ +cache[$key]); + } + /** * @param string $key The object KEY - * @param int $ttl IGNORED IN MEMCACHED. + * @param int $default IGNORED IN MEMCACHED. * @return object Description */ - public function get($key, $ttl = 0) + public function get($key, $default = null) { - - - if (array_key_exists($key, $this->_L1Cache)) { + if ($this->has($key)) { $this->logger->info("[Array cache] Get '$key' from L1 Cache"); - return $this->_L1Cache[$key]; + return $this->cache[$key]; } else { $this->logger->info("[Array cache] Not found '$key'"); - return null; + return $default; } } /** * @param string $key The object Key - * @param object $object The object to be cached + * @param object $value The object to be cached * @param int $ttl The time to live in seconds of this objects * @return bool If the object is successfully posted */ - public function set($key, $object, $ttl = 0) + public function set($key, $value, $ttl = 0) { $this->logger->info("[Array cache] Set '$key' in L1 Cache"); - $this->_L1Cache[$key] = $object; + $this->cache[$key] = $value; return true; } - /** - * - * @param string $key - * @param string $str - * @return bool - */ - public function append($key, $str) + public function clear() { - $this->logger->info("[Array cache] Append '$key' in L1 Cache"); - - $this->_L1Cache[$key] = $this->_L1Cache[$key] . $str; - - return true; + $this->cache = []; } /** * Unlock resource + * * @param string $key + * @return bool|void */ - public function release($key) - { - unset($this->_L1Cache[$key]); - } - - /** - * Lock resource before set it. - * @param string $key - */ - public function lock($key) - { - return; - } - - /** - * UnLock resource after set it - * @param string $key - */ - public function unlock($key) + public function delete($key) { - return; + unset($this->cache[$key]); + return true; } public function isAvailable() diff --git a/src/Engine/BaseCacheEngine.php b/src/Engine/BaseCacheEngine.php new file mode 100644 index 0000000..4945b1c --- /dev/null +++ b/src/Engine/BaseCacheEngine.php @@ -0,0 +1,31 @@ +get($key, $default); + } + return $result; + } + + public function setMultiple($values, $ttl = null) + { + foreach ($values as $key => $value) { + $this->set($key, $value, $ttl); + } + } + + public function deleteMultiple($keys) + { + foreach ($keys as $key) { + $this->delete($key); + } + } +} \ No newline at end of file diff --git a/src/Engine/NoCacheEngine.php b/src/Engine/NoCacheEngine.php index 3eb4db8..a898047 100644 --- a/src/Engine/NoCacheEngine.php +++ b/src/Engine/NoCacheEngine.php @@ -2,28 +2,28 @@ namespace ByJG\Cache\Engine; -use ByJG\Cache\CacheEngineInterface; +use ByJG\Cache\CacheAvailabilityInterface; +use ByJG\Cache\CacheLockInterface; -class NoCacheEngine implements CacheEngineInterface +class NoCacheEngine extends BaseCacheEngine implements CacheLockInterface, CacheAvailabilityInterface { - /** * @param string $key The object KEY - * @param int $ttl IGNORED IN MEMCACHED. - * @return object Description + * @param int $default IGNORED IN MEMCACHED. + * @return mixed Description */ - public function get($key, $ttl = 0) + public function get($key, $default = null) { - return null; + return $default; } /** * @param string $key The object Key - * @param object $object The object to be cached + * @param object $value The object to be cached * @param int $ttl The time to live in seconds of this objects * @return bool If the object is successfully posted */ - public function set($key, $object, $ttl = 0) + public function set($key, $value, $ttl = 0) { return true; } @@ -32,18 +32,7 @@ public function set($key, $object, $ttl = 0) * Unlock resource * @param string $key */ - public function release($key) - { - return; - } - - /** - * - * @param string $key - * @param string $str - * @return bool - */ - public function append($key, $str) + public function delete($key) { return true; } @@ -71,5 +60,30 @@ public function isAvailable() return true; } + /** + * Wipes clean the entire cache's keys. + * + * @return bool True on success and false on failure. + */ + public function clear() + { + return true; + } + /** + * Determines whether an item is present in the cache. + * NOTE: It is recommended that has() is only to be used for cache warming type purposes + * and not to be used within your live applications operations for get/set, as this method + * is subject to a race condition where your has() will return true and immediately after, + * another script can remove it making the state of your app out of date. + * + * @param string $key The cache item key. + * @return bool + * @throws \Psr\SimpleCache\InvalidArgumentException + * MUST be thrown if the $key string is not a legal value. + */ + public function has($key) + { + return false; + } } diff --git a/src/Psr/CacheItem.php b/src/Psr6/CacheItem.php similarity index 95% rename from src/Psr/CacheItem.php rename to src/Psr6/CacheItem.php index 6802a09..c94ad53 100644 --- a/src/Psr/CacheItem.php +++ b/src/Psr6/CacheItem.php @@ -1,12 +1,6 @@ _cacheEngine = $_cacheEngine; $this->bufferSize = intval($bufferSize); @@ -186,7 +187,7 @@ public function deleteItem($key) public function deleteItems(array $keys) { foreach ($keys as $key) { - $this->_cacheEngine->release($key); + $this->_cacheEngine->delete($key); $this->removeElementFromBuffer($key); } diff --git a/tests/CachePoolTest.php b/tests/CachePoolTest.php index 76f0402..a9961c8 100644 --- a/tests/CachePoolTest.php +++ b/tests/CachePoolTest.php @@ -6,7 +6,7 @@ */ -use ByJG\Cache\Psr\CachePool; +use ByJG\Cache\Psr6\CachePool; class CachePoolTest extends PHPUnit_Framework_TestCase From 0859a5b68ae25a2fc085a9b1b55ecba4cd1ac051 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Fri, 26 May 2017 18:50:33 -0300 Subject: [PATCH 02/16] More implementing for PSR-16 --- src/Engine/FileSystemCacheEngine.php | 80 ++++++++++++------------ src/Engine/MemcachedEngine.php | 12 ++-- src/Engine/RedisCacheEngine.php | 12 ++-- src/Engine/SessionCacheEngine.php | 47 +++++--------- src/Engine/ShmopCacheEngine.php | 91 ++++++++++------------------ src/Psr6/CachePool.php | 5 +- tests/CachePoolTest.php | 25 ++++---- 7 files changed, 117 insertions(+), 155 deletions(-) diff --git a/src/Engine/FileSystemCacheEngine.php b/src/Engine/FileSystemCacheEngine.php index f7f9bd7..929fc3c 100644 --- a/src/Engine/FileSystemCacheEngine.php +++ b/src/Engine/FileSystemCacheEngine.php @@ -2,11 +2,12 @@ namespace ByJG\Cache\Engine; -use ByJG\Cache\CacheEngineInterface; +use ByJG\Cache\CacheAvailabilityInterface; +use ByJG\Cache\CacheLockInterface; use Exception; use Psr\Log\NullLogger; -class FileSystemCacheEngine implements CacheEngineInterface +class FileSystemCacheEngine extends BaseCacheEngine implements CacheAvailabilityInterface, CacheLockInterface { protected $logger = null; @@ -25,16 +26,11 @@ public function __construct($prefix = 'cache', $logger = null) /** * @param string $key The object KEY - * @param int $ttl IGNORED IN MEMCACHED. + * @param int $default IGNORED IN MEMCACHED. * @return object Description */ - public function get($key, $ttl = 0) + public function get($key, $default = null) { - if ($ttl === false) { - $this->logger->info("[Filesystem cache] Ignored $key because TTL=FALSE"); - return null; - } - // Check if file is Locked $fileKey = $this->fixKey($key); $lockFile = $fileKey . ".lock"; @@ -57,10 +53,10 @@ public function get($key, $ttl = 0) } // Check if file exists - if (file_exists($fileKey)) { + if ($this->has($key)) { $fileAge = filemtime($fileKey); - if (($ttl > 0) && (intval(time() - $fileAge) > $ttl)) { + if (($default > 0) && (intval(time() - $fileAge) > $default)) { $this->logger->info("[Filesystem cache] File too old. Ignoring '$key'"); return null; } else { @@ -75,11 +71,11 @@ public function get($key, $ttl = 0) /** * @param string $key The object Key - * @param object $object The object to be cached + * @param object $value The object to be cached * @param int $ttl The time to live in seconds of this objects * @return bool If the object is successfully posted */ - public function set($key, $object, $ttl = 0) + public function set($key, $value, $ttl = 0) { $fileKey = $this->fixKey($key); @@ -90,14 +86,14 @@ public function set($key, $object, $ttl = 0) unlink($fileKey); } - if (is_null($object)) { + if (is_null($value)) { return false; } - if (is_string($object) && (strlen($object) === 0)) { + if (is_string($value) && (strlen($value) === 0)) { touch($fileKey); } else { - file_put_contents($fileKey, serialize($object)); + file_put_contents($fileKey, serialize($value)); } } catch (Exception $ex) { $this->logger->warning("[Filesystem cache] I could not write to cache on file '" . basename($key) . "'. Switching to nocache=true mode."); @@ -111,33 +107,11 @@ public function set($key, $object, $ttl = 0) * Unlock resource * @param string $key */ - public function release($key) + public function delete($key) { $this->set($key, null); } - /** - * @param string $key The object Key - * @param string $content The object to be cached - * @param int $ttl The time to live in seconds of this objects - * @return bool If the object is successfully posted - */ - public function append($key, $content, $ttl = 0) - { - $fileKey = $this->fixKey($key); - - $this->logger->info("[Filesystem cache] Append '$key' in FileSystem"); - - try { - file_put_contents($fileKey, serialize($content), true); - } catch (Exception $ex) { - $this->logger->warning("[Filesystem cache] I could not write to cache on file '" . basename($key) . "'. Switching to nocache=true mode."); - return false; - } - - return true; - } - /** * Lock resource before set it. * @param string $key @@ -183,4 +157,32 @@ protected function fixKey($key) . '-' . preg_replace("/[\/\\\]/", "#", $key) . '.cache'; } + + /** + * Wipes clean the entire cache's keys. + * + * @return bool True on success and false on failure. + */ + public function clear() + { + // TODO: Implement clear() method. + } + + /** + * Determines whether an item is present in the cache. + * NOTE: It is recommended that has() is only to be used for cache warming type purposes + * and not to be used within your live applications operations for get/set, as this method + * is subject to a race condition where your has() will return true and immediately after, + * another script can remove it making the state of your app out of date. + * + * @param string $key The cache item key. + * @return bool + * @throws \Psr\SimpleCache\InvalidArgumentException + * MUST be thrown if the $key string is not a legal value. + */ + public function has($key) + { + $fileKey = $this->fixKey($key); + return file_exists($fileKey); + } } diff --git a/src/Engine/MemcachedEngine.php b/src/Engine/MemcachedEngine.php index ef87bc9..4052c55 100644 --- a/src/Engine/MemcachedEngine.php +++ b/src/Engine/MemcachedEngine.php @@ -52,10 +52,10 @@ protected function lazyLoadMemCachedServers() /** * @param string $key The object KEY - * @param int $ttl IGNORED IN MEMCACHED. + * @param int $default IGNORED IN MEMCACHED. * @return object Description */ - public function get($key, $ttl = 0) + public function get($key, $default = 0) { $this->lazyLoadMemCachedServers(); @@ -70,15 +70,15 @@ public function get($key, $ttl = 0) /** * @param string $key The object Key - * @param object $object The object to be cached + * @param object $value The object to be cached * @param int $ttl The time to live in seconds of this objects * @return bool If the object is successfully posted */ - public function set($key, $object, $ttl = 0) + public function set($key, $value, $ttl = 0) { $this->lazyLoadMemCachedServers(); - $this->memCached->set($key, $object, $ttl); + $this->memCached->set($key, $value, $ttl); $this->logger->info("[Memcached] Set '$key' result " . $this->memCached->getResultCode()); if ($this->memCached->getResultCode() !== Memcached::RES_SUCCESS) { $this->logger->error("[Memcached] Set '$key' failed with status " . $this->memCached->getResultCode()); @@ -91,7 +91,7 @@ public function set($key, $object, $ttl = 0) * Unlock resource * @param string $key */ - public function release($key) + public function delete($key) { $this->lazyLoadMemCachedServers(); diff --git a/src/Engine/RedisCacheEngine.php b/src/Engine/RedisCacheEngine.php index 6258aea..f962a3f 100644 --- a/src/Engine/RedisCacheEngine.php +++ b/src/Engine/RedisCacheEngine.php @@ -53,10 +53,10 @@ protected function lazyLoadRedisServer() /** * @param string $key The object KEY - * @param int $ttl IGNORED IN MEMCACHED. + * @param int $default IGNORED IN MEMCACHED. * @return object Description */ - public function get($key, $ttl = 0) + public function get($key, $default = 0) { $this->lazyLoadRedisServer(); @@ -68,15 +68,15 @@ public function get($key, $ttl = 0) /** * @param string $key The object Key - * @param object $object The object to be cached + * @param object $value The object to be cached * @param int $ttl The time to live in seconds of this objects * @return bool If the object is successfully posted */ - public function set($key, $object, $ttl = 0) + public function set($key, $value, $ttl = 0) { $this->lazyLoadRedisServer(); - $this->redis->set($key, $object, $ttl); + $this->redis->set($key, $value, $ttl); $this->logger->info("[Redis Cache] Set '$key' result "); return true; @@ -86,7 +86,7 @@ public function set($key, $object, $ttl = 0) * Unlock resource * @param string $key */ - public function release($key) + public function delete($key) { $this->lazyLoadRedisServer(); diff --git a/src/Engine/SessionCacheEngine.php b/src/Engine/SessionCacheEngine.php index e344d39..4a39c44 100644 --- a/src/Engine/SessionCacheEngine.php +++ b/src/Engine/SessionCacheEngine.php @@ -2,9 +2,10 @@ namespace ByJG\Cache\Engine; -use ByJG\Cache\CacheEngineInterface; +use ByJG\Cache\CacheAvailabilityInterface; +use ByJG\Cache\CacheLockInterface; -class SessionCacheEngine implements CacheEngineInterface +class SessionCacheEngine extends BaseCacheEngine implements CacheAvailabilityInterface { protected $prefix = null; @@ -32,21 +33,7 @@ protected function keyName($key) return $this->prefix . '-' . $key; } - public function append($key, $str) - { - $this->checkSession(); - - $keyName = $this->keyName($key); - - $current = $this->get($keyName); - if ($current === false) { - $this->set($keyName, $str); - } else { - $this->set($keyName, $current . $str); - } - } - - public function get($key, $ttl = 0) + public function get($key, $default = null) { $this->checkSession(); @@ -55,18 +42,11 @@ public function get($key, $ttl = 0) if (isset($_SESSION[$keyName])) { return $_SESSION[$keyName]; } else { - return null; + return $default; } } - public function lock($key) - { - $this->checkSession(); - - // Nothing to implement here; - } - - public function release($key) + public function delete($key) { $this->checkSession(); @@ -77,19 +57,24 @@ public function release($key) } } - public function set($key, $object, $ttl = 0) + public function set($key, $value, $ttl = 0) { $this->checkSession(); $keyName = $this->keyName($key); - $_SESSION[$keyName] = $object; + $_SESSION[$keyName] = $value; } - public function unlock($key) + public function clear() { - $this->checkSession(); + session_destroy(); + } + + public function has($key) + { + $keyName = $this->keyName($key); - // Nothing to implement here; + return (isset($_SESSION[$keyName])); } public function isAvailable() diff --git a/src/Engine/ShmopCacheEngine.php b/src/Engine/ShmopCacheEngine.php index 7557961..8d5b815 100644 --- a/src/Engine/ShmopCacheEngine.php +++ b/src/Engine/ShmopCacheEngine.php @@ -2,6 +2,7 @@ namespace ByJG\Cache\Engine; +use ByJG\Cache\CacheAvailabilityInterface; use ByJG\Cache\CacheEngineInterface; use InvalidArgumentException; use Psr\Log\NullLogger; @@ -21,9 +22,8 @@ * * */ -class ShmopCacheEngine implements CacheEngineInterface +class ShmopCacheEngine extends BaseCacheEngine implements CacheAvailabilityInterface { - protected $logger = null; protected $config = []; @@ -71,14 +71,12 @@ protected function getKeyId($key) /** * @param string $key The object KEY - * @param int $ttl The time to live in seconds of the object. Depends on implementation. + * @param int $default The time to live in seconds of the object. Depends on implementation. * @return object The Object */ - public function get($key, $ttl = 0) + public function get($key, $default = null) { - - - if ($ttl === false) { + if ($default === false) { $this->logger->info("[Shmop Cache] Ignored $key because TTL=FALSE"); return null; } @@ -95,7 +93,7 @@ public function get($key, $ttl = 0) $fileAge = filemtime($this->getFTok($key)); // Check - if (($ttl > 0) && (intval(time() - $fileAge) > $ttl)) { + if (($default > 0) && (intval(time() - $fileAge) > $default)) { $this->logger->info("[Shmop Cache] File too old. Ignoring '$key'"); // Close old descriptor @@ -118,18 +116,18 @@ public function get($key, $ttl = 0) /** * @param string $key The object Key - * @param object $object The object to be cached + * @param object $value The object to be cached * @param int $ttl The time to live in seconds of the object. Depends on implementation. * @return bool If the object is successfully posted * @throws \Exception */ - public function set($key, $object, $ttl = 0) + public function set($key, $value, $ttl = 0) { $this->logger->info("[Shmop Cache] set '$key'"); - $this->release($key); + $this->delete($key); - $serialized = serialize($object); + $serialized = serialize($value); $size = strlen($serialized); if ($size > $this->getMaxSize()) { @@ -157,57 +155,12 @@ public function set($key, $object, $ttl = 0) return true; } - /** - * Append only will work with strings. - * - * @param string $key - * @param string $str - * @return bool - */ - public function append($key, $str) - { - $old = $this->get($key); - if ($old === false) { - $this->set($key, $str); - } else { - $oldUn = unserialize($old); - if (is_string($oldUn)) { - $this->release($key); - $this->set($key, $oldUn . $str); - } else { - throw new InvalidArgumentException('Only is possible append string types'); - } - } - - return true; - } - - /** - * Lock resource before set it. - * @param string $key - */ - public function lock($key) - { - - } - - /** - * Unlock resource - * @param string $key - */ - public function unlock($key) - { - - } - /** * Release the object * @param string $key */ - public function release($key) + public function delete($key) { - - $this->logger->info("[Shmop Cache] release '$key'"); if ($this->get($key) === false) { @@ -231,6 +184,28 @@ public function release($key) } } + public function clear() + { + + } + + public function has($key) + { + $fileKey = $this->getKeyId($key); + + // Opened + $shm_id = @shmop_open($fileKey, "a", 0, 0); + + $exists = !(!$shm_id); + + if ($exists) { + shmop_close($shm_id); + } + + return $exists; + } + + public function isAvailable() { return function_exists('shmop_open'); diff --git a/src/Psr6/CachePool.php b/src/Psr6/CachePool.php index edec471..a4eba2d 100644 --- a/src/Psr6/CachePool.php +++ b/src/Psr6/CachePool.php @@ -3,6 +3,7 @@ namespace ByJG\Cache\Psr6; use ByJG\Cache\CacheEngineInterface; +use ByJG\Cache\Engine\BaseCacheEngine; use Psr\Cache\CacheItemInterface; use Psr\Cache\CacheItemPoolInterface; use Psr\Log\InvalidArgumentException; @@ -38,10 +39,10 @@ class CachePool implements CacheItemPoolInterface /** * CachePool constructor. * - * @param CacheInterface $_cacheEngine + * @param BaseCacheEngine $_cacheEngine * @param int $bufferSize */ - public function __construct(CacheInterface $_cacheEngine, $bufferSize = 10) + public function __construct(BaseCacheEngine $_cacheEngine, $bufferSize = 10) { $this->_cacheEngine = $_cacheEngine; $this->bufferSize = intval($bufferSize); diff --git a/tests/CachePoolTest.php b/tests/CachePoolTest.php index a9961c8..872719d 100644 --- a/tests/CachePoolTest.php +++ b/tests/CachePoolTest.php @@ -1,15 +1,14 @@ Date: Fri, 26 May 2017 22:02:27 -0300 Subject: [PATCH 03/16] Fix more bugs in PSR-16 implementation. --- src/Engine/ArrayCacheEngine.php | 7 +- src/Engine/BaseCacheEngine.php | 5 +- src/Engine/FileSystemCacheEngine.php | 28 +++--- src/Engine/NoCacheEngine.php | 3 +- src/Engine/SessionCacheEngine.php | 5 +- src/Engine/ShmopCacheEngine.php | 73 +++++++++------- tests/CachePoolTest.php | 124 +++++++++++++++++++++++---- 7 files changed, 172 insertions(+), 73 deletions(-) diff --git a/src/Engine/ArrayCacheEngine.php b/src/Engine/ArrayCacheEngine.php index 098511f..ec5779d 100644 --- a/src/Engine/ArrayCacheEngine.php +++ b/src/Engine/ArrayCacheEngine.php @@ -2,11 +2,10 @@ namespace ByJG\Cache\Engine; -use ByJG\Cache\CacheAvailabilityInterface; use Psr\Log\NullLogger; use Psr\SimpleCache\DateInterval; -class ArrayCacheEngine extends BaseCacheEngine implements CacheAvailabilityInterface +class ArrayCacheEngine extends BaseCacheEngine { protected $cache = array(); @@ -32,8 +31,8 @@ public function has($key) /** * @param string $key The object KEY - * @param int $default IGNORED IN MEMCACHED. - * @return object Description + * @param mixed $default IGNORED IN MEMCACHED. + * @return mixed Description */ public function get($key, $default = null) { diff --git a/src/Engine/BaseCacheEngine.php b/src/Engine/BaseCacheEngine.php index 4945b1c..af1390e 100644 --- a/src/Engine/BaseCacheEngine.php +++ b/src/Engine/BaseCacheEngine.php @@ -2,9 +2,10 @@ namespace ByJG\Cache\Engine; +use ByJG\Cache\CacheAvailabilityInterface; use Psr\SimpleCache\CacheInterface; -abstract class BaseCacheEngine implements CacheInterface +abstract class BaseCacheEngine implements CacheInterface, CacheAvailabilityInterface { public function getMultiple($keys, $default = null) { @@ -28,4 +29,6 @@ public function deleteMultiple($keys) $this->delete($key); } } + + abstract public function isAvailable(); } \ No newline at end of file diff --git a/src/Engine/FileSystemCacheEngine.php b/src/Engine/FileSystemCacheEngine.php index 929fc3c..8807770 100644 --- a/src/Engine/FileSystemCacheEngine.php +++ b/src/Engine/FileSystemCacheEngine.php @@ -2,12 +2,11 @@ namespace ByJG\Cache\Engine; -use ByJG\Cache\CacheAvailabilityInterface; use ByJG\Cache\CacheLockInterface; use Exception; use Psr\Log\NullLogger; -class FileSystemCacheEngine extends BaseCacheEngine implements CacheAvailabilityInterface, CacheLockInterface +class FileSystemCacheEngine extends BaseCacheEngine implements CacheLockInterface { protected $logger = null; @@ -26,8 +25,8 @@ public function __construct($prefix = 'cache', $logger = null) /** * @param string $key The object KEY - * @param int $default IGNORED IN MEMCACHED. - * @return object Description + * @param mixed $default IGNORED IN MEMCACHED. + * @return mixed Description */ public function get($key, $default = null) { @@ -46,7 +45,7 @@ public function get($key, $default = null) if (intval(time() - $lockTime) > 20) { // Wait for 10 seconds $this->logger->info("[Filesystem cache] Gave up to wait unlock. Release lock for '$key'"); $this->unlock($key); - return null; + return $default; } sleep(1); // 1 second } @@ -56,16 +55,17 @@ public function get($key, $default = null) if ($this->has($key)) { $fileAge = filemtime($fileKey); - if (($default > 0) && (intval(time() - $fileAge) > $default)) { - $this->logger->info("[Filesystem cache] File too old. Ignoring '$key'"); - return null; - } else { + // @todo Resolve TTL! + // if (($default > 0) && (intval(time() - $fileAge) > $default)) { + // $this->logger->info("[Filesystem cache] File too old. Ignoring '$key'"); + // return $default; + // } else { $this->logger->info("[Filesystem cache] Get '$key'"); return unserialize(file_get_contents($fileKey)); - } + // } } else { $this->logger->info("[Filesystem cache] Not found '$key'"); - return null; + return $default; } } @@ -165,7 +165,11 @@ protected function fixKey($key) */ public function clear() { - // TODO: Implement clear() method. + $patternKey = $this->fixKey('*'); + $list = glob($patternKey); + foreach ($list as $file) { + unlink($file); + } } /** diff --git a/src/Engine/NoCacheEngine.php b/src/Engine/NoCacheEngine.php index a898047..65b89d6 100644 --- a/src/Engine/NoCacheEngine.php +++ b/src/Engine/NoCacheEngine.php @@ -2,10 +2,9 @@ namespace ByJG\Cache\Engine; -use ByJG\Cache\CacheAvailabilityInterface; use ByJG\Cache\CacheLockInterface; -class NoCacheEngine extends BaseCacheEngine implements CacheLockInterface, CacheAvailabilityInterface +class NoCacheEngine extends BaseCacheEngine implements CacheLockInterface { /** * @param string $key The object KEY diff --git a/src/Engine/SessionCacheEngine.php b/src/Engine/SessionCacheEngine.php index 4a39c44..278536d 100644 --- a/src/Engine/SessionCacheEngine.php +++ b/src/Engine/SessionCacheEngine.php @@ -2,10 +2,7 @@ namespace ByJG\Cache\Engine; -use ByJG\Cache\CacheAvailabilityInterface; -use ByJG\Cache\CacheLockInterface; - -class SessionCacheEngine extends BaseCacheEngine implements CacheAvailabilityInterface +class SessionCacheEngine extends BaseCacheEngine { protected $prefix = null; diff --git a/src/Engine/ShmopCacheEngine.php b/src/Engine/ShmopCacheEngine.php index 8d5b815..5e26bad 100644 --- a/src/Engine/ShmopCacheEngine.php +++ b/src/Engine/ShmopCacheEngine.php @@ -2,9 +2,7 @@ namespace ByJG\Cache\Engine; -use ByJG\Cache\CacheAvailabilityInterface; use ByJG\Cache\CacheEngineInterface; -use InvalidArgumentException; use Psr\Log\NullLogger; /** @@ -22,7 +20,7 @@ * * */ -class ShmopCacheEngine extends BaseCacheEngine implements CacheAvailabilityInterface +class ShmopCacheEngine extends BaseCacheEngine { protected $logger = null; @@ -47,7 +45,7 @@ public function __construct($config = [], $logger = null) protected function getFTok($key) { - return sys_get_temp_dir() . '/' . sha1($key); + return sys_get_temp_dir() . '/shmop-' . sha1($key) . '.cache'; } protected function getMaxSize() @@ -60,9 +58,8 @@ protected function getDefaultPermission() return $this->config['default-permission']; } - protected function getKeyId($key) + protected function getKeyId($file) { - $file = $this->getFTok($key); if (!file_exists($file)) { touch($file); } @@ -71,40 +68,41 @@ protected function getKeyId($key) /** * @param string $key The object KEY - * @param int $default The time to live in seconds of the object. Depends on implementation. - * @return object The Object + * @param mixed $default The time to live in seconds of the object. Depends on implementation. + * @return mixed The Object */ public function get($key, $default = null) { if ($default === false) { $this->logger->info("[Shmop Cache] Ignored $key because TTL=FALSE"); - return null; + return $default; } - $fileKey = $this->getKeyId($key); + $file = $this->getFTok($key); + $fileKey = $this->getKeyId($file); // Opened $shm_id = @shmop_open($fileKey, "a", 0, 0); if (!$shm_id) { $this->logger->info("[Shmop Cache] '$key' not exists"); - return null; + return $default; } - $fileAge = filemtime($this->getFTok($key)); - - // Check - if (($default > 0) && (intval(time() - $fileAge) > $default)) { - $this->logger->info("[Shmop Cache] File too old. Ignoring '$key'"); - - // Close old descriptor - shmop_close($shm_id); - - // delete old memory segment - $shm_id = shmop_open($fileKey, "w", $this->getDefaultPermission(), $this->getMaxSize()); - shmop_delete($shm_id); - shmop_close($shm_id); - return null; - } + // $fileAge = filemtime($this->getFTok($key)); + + // Check @todo TTL + // if (($default > 0) && (intval(time() - $fileAge) > $default)) { + // $this->logger->info("[Shmop Cache] File too old. Ignoring '$key'"); + // + // // Close old descriptor + // shmop_close($shm_id); + // + // // delete old memory segment + // $shm_id = shmop_open($fileKey, "w", $this->getDefaultPermission(), $this->getMaxSize()); + // shmop_delete($shm_id); + // shmop_close($shm_id); + // return $default; + // } $this->logger->info("[Shmop Cache] Get '$key'"); @@ -134,7 +132,8 @@ public function set($key, $value, $ttl = 0) throw new \Exception('Object is greater than the max size allowed: ' . $this->getMaxSize()); } - $shmKey = $this->getKeyId($key); + $file = $this->getFTok($key); + $shmKey = $this->getKeyId($file); $shm_id = shmop_open($shmKey, "c", 0777, $size); if (!$shm_id) { $message = "Couldn't create shared memory segment"; @@ -168,10 +167,15 @@ public function delete($key) return; } - $filekey = $this->getKeyId($key); + $file = $this->getFTok($key); + $this->deleteFromFTok($file); + } + + private function deleteFromFTok($file) + { + $filekey = $this->getKeyId($file); $shm_id = @shmop_open($filekey, "w", 0, 0); - $file = $this->getFTok($key); if (file_exists($file)) { unlink($file); } @@ -180,18 +184,23 @@ public function delete($key) shmop_delete($shm_id); shmop_close($shm_id); - $this->logger->info("[Shmop Cache] release '$key' confirmed."); + $this->logger->info("[Shmop Cache] release confirmed."); } } public function clear() { - + $patternKey = sys_get_temp_dir() . '/shmop-*.cache'; + $list = glob($patternKey); + foreach ($list as $file) { + $this->deleteFromFTok($file); + } } public function has($key) { - $fileKey = $this->getKeyId($key); + $file = $this->getFTok($key); + $fileKey = $this->getKeyId($file); // Opened $shm_id = @shmop_open($fileKey, "a", 0, 0); diff --git a/tests/CachePoolTest.php b/tests/CachePoolTest.php index 872719d..792cb35 100644 --- a/tests/CachePoolTest.php +++ b/tests/CachePoolTest.php @@ -10,6 +10,10 @@ class_alias('\PHPUnit_Framework_TestCase', '\PHPUnit\Framework\TestCase'); class CachePoolTest extends \PHPUnit\Framework\TestCase { + /** + * @var \ByJG\Cache\Engine\BaseCacheEngine + */ + private $cacheEngine = null; protected function setUp() { @@ -18,7 +22,8 @@ protected function setUp() protected function tearDown() { - + $this->cacheEngine->clear(); + $this->cacheEngine = null; } public function CachePoolProvider() @@ -28,36 +33,40 @@ public function CachePoolProvider() $redisPassword = ''; return [ - [ - new CachePool(new \ByJG\Cache\Engine\ArrayCacheEngine()) + 'Array' => [ + new \ByJG\Cache\Engine\ArrayCacheEngine() ], - [ - new CachePool(new \ByJG\Cache\Engine\FileSystemCacheEngine()) + 'FileSystem' => [ + new \ByJG\Cache\Engine\FileSystemCacheEngine() ], - [ - new CachePool(new \ByJG\Cache\Engine\ShmopCacheEngine()) + 'ShmopCache' => [ + new \ByJG\Cache\Engine\ShmopCacheEngine() ], - [ - new CachePool(new \ByJG\Cache\Engine\SessionCacheEngine()) + 'SessionCache' => [ + new \ByJG\Cache\Engine\SessionCacheEngine() ], - [ - new CachePool(new \ByJG\Cache\Engine\NoCacheEngine()) + 'NoCacheEngine' => [ + new \ByJG\Cache\Engine\NoCacheEngine() ], // [ - // new CachePool(new \ByJG\Cache\Engine\MemcachedEngine($memcachedServer)) + // new \ByJG\Cache\Engine\MemcachedEngine($memcachedServer) // ], // [ - // new CachePool(new \ByJG\Cache\Engine\RedisCacheEngine($redisCacheServer, $redisPassword)) + // new \ByJG\Cache\Engine\RedisCacheEngine($redisCacheServer, $redisPassword) // ] ]; } /** * @dataProvider CachePoolProvider - * @param CachePool $object + * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine */ - public function testGetOneItem($object) + public function testGetOneItemPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) { + $this->cacheEngine = $cacheEngine; + + // PSR-6 Test + $object = new CachePool($cacheEngine); if ($object->isAvailable()) { // First time $item = $object->getItem('chave'); @@ -86,12 +95,15 @@ public function testGetOneItem($object) /** * @dataProvider CachePoolProvider - * @param CachePool $object + * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine */ - public function testGetMultipleItems($object) + public function testGetMultipleItemsPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) { - if ($object->isAvailable()) { + $this->cacheEngine = $cacheEngine; + // PSR-6 Test + $object = new CachePool($cacheEngine); + if ($object->isAvailable()) { // First time $items = $object->getItems(['chave1', 'chave2']); $this->assertFalse($items[0]->isHit()); @@ -125,4 +137,80 @@ public function testGetMultipleItems($object) } } + /** + * @dataProvider CachePoolProvider + * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + */ + public function testGetOneItemPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + { + $this->cacheEngine = $cacheEngine; + + // PSR-6 Test + if ($cacheEngine->isAvailable()) { + // First time + $item = $cacheEngine->get('chave', null); + $this->assertEquals(null, $item); + $item = $cacheEngine->get('chave', 'default'); + $this->assertEquals('default', $item); + + // Set object + $cacheEngine->set('chave', 'valor'); + + // Get Object + if (!($cacheEngine instanceof \ByJG\Cache\Engine\NoCacheEngine)) { + $item2 = $cacheEngine->get('chave', 'default'); + $this->assertEquals('valor', $item2); + } + + // Remove + $cacheEngine->delete('chave'); + + // Check Removed + $item = $cacheEngine->get('chave'); + $this->assertEquals(null, $item); + } else { + $this->markTestIncomplete('Object is not fully functional'); + } + } + + /** + * @dataProvider CachePoolProvider + * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + */ + public function testGetMultipleItemsPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + { + $this->cacheEngine = $cacheEngine; + + // PSR-6 Test + if ($cacheEngine->isAvailable()) { + // First time + $items = $cacheEngine->getMultiple(['chave1', 'chave2']); + $this->assertEquals(null, $items['chave1']); + $this->assertEquals(null, $items['chave2']); + $items = $cacheEngine->getMultiple(['chave1', 'chave2'], 'default'); + $this->assertEquals('default', $items['chave1']); + $this->assertEquals('default', $items['chave2']); + + // Set object + $cacheEngine->set('chave1', 'valor1'); + $cacheEngine->set('chave2', 'valor2'); + + // Get Object + if (!($cacheEngine instanceof \ByJG\Cache\Engine\NoCacheEngine)) { + $item2 = $cacheEngine->getMultiple(['chave1', 'chave2']); + $this->assertEquals('valor1', $item2['chave1']); + $this->assertEquals('valor2', $item2['chave2']); + } + + // Remove + $cacheEngine->deleteMultiple(['chave1', 'chave2']); + + // Check Removed + $items = $cacheEngine->getMultiple(['chave1', 'chave2']); + $this->assertEquals(null, $items['chave1']); + $this->assertEquals(null, $items['chave2']); + } else { + $this->markTestIncomplete('Object is not fully functional'); + } + } } From 842a4710da6871a32fbd6e9bb6e691817951826e Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Fri, 26 May 2017 22:14:38 -0300 Subject: [PATCH 04/16] Update README.md --- README.md | 44 +++++++++++++++++++++++++++++++------------- composer.json | 2 +- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 7555215..10cb04c 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,12 @@ ## Description -A multi-purpose cache engine in PHP with several drivers. PSR-6 compliant. +A multi-purpose cache engine PSR-6 and PSR-16 implementation with several drivers. -## Avaible cache engines +## Cache Engine PSR-16 compliant + +PSR-16 defines a Simple Cache interface with less verbosity than PSR-6. Below a list +of engines available in this library that is PSR-16 compliant: | Class | Description | |:----------------------------------|:--------------------------------------------------------------------| @@ -19,28 +22,39 @@ A multi-purpose cache engine in PHP with several drivers. PSR-6 compliant. | \ByJG\Cache\SessionCachedEngine | uses the PHP session as cache | | \ByJG\Cache\ShmopCachedEngine | uses the shared memory area for cache | -## Create new cache instance +To create a new Cache Instance just create the proper cache engine and use it: + +```php +get('key'); +$cache->set('key', 'value'); +if ($cache->has('key')) { + //... +}; +``` + +## Cache Engine PSR-6 compliant -### Creating a PSR-6 compatible instance +The PSR-6 implementation use the engines defined above. PSR-6 is more verbosity and +have an extra layer do get and set the cache values. -You can set instance in the 'cacheconfig.php' setup (see below how to configure the factory) +You can use one of the factory methods to create a instance of the CachePool implementation: ```php + 524288, 'default-permission' => '0700' ]` +## Logging cache commands + +You can add a PSR Log compatible to the constructor in order to get Log of the operations + ## Install -Just type: `composer require "byjg/cache-engine=3.0.*"` +Just type: `composer require "byjg/cache-engine=4.0.*"` ## Running Unit Testes diff --git a/composer.json b/composer.json index 9ce1306..0b161e3 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "byjg/cache-engine", - "description": "A multi-purpose cache engine in PHP with several drivers. PSR-6 compliant.", + "description": "A multi-purpose cache engine PSR-6 and PSR-16 implementation with several drivers.", "authors": [ { "name": "João Gilberto Magalhães", From 51fe1bfb7064a08abb2bfd6acceb78fa99724503 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sat, 27 May 2017 12:15:54 -0300 Subject: [PATCH 05/16] Fixed TTL in FileSystemCacheEngine --- src/Engine/BaseCacheEngine.php | 13 +++++++ src/Engine/FileSystemCacheEngine.php | 43 +++++++++++++++------- tests/{CachePoolTest.php => CacheTest.php} | 32 +++++++++++++++- 3 files changed, 74 insertions(+), 14 deletions(-) rename tests/{CachePoolTest.php => CacheTest.php} (87%) diff --git a/src/Engine/BaseCacheEngine.php b/src/Engine/BaseCacheEngine.php index af1390e..b8c8dd6 100644 --- a/src/Engine/BaseCacheEngine.php +++ b/src/Engine/BaseCacheEngine.php @@ -31,4 +31,17 @@ public function deleteMultiple($keys) } abstract public function isAvailable(); + + protected function addToNow($ttl) + { + if (is_numeric($ttl)) { + return strtotime("+$ttl second"); + } + + if ($ttl instanceof \DateInterval) { + $now = new \DateTime(); + $now->add($ttl); + return $now->getTimestamp(); + } + } } \ No newline at end of file diff --git a/src/Engine/FileSystemCacheEngine.php b/src/Engine/FileSystemCacheEngine.php index 8807770..03cff3f 100644 --- a/src/Engine/FileSystemCacheEngine.php +++ b/src/Engine/FileSystemCacheEngine.php @@ -53,16 +53,18 @@ public function get($key, $default = null) // Check if file exists if ($this->has($key)) { - $fileAge = filemtime($fileKey); + if (file_exists("$fileKey.ttl")) { + $fileTtl = intval(file_get_contents("$fileKey.ttl")); + } - // @todo Resolve TTL! - // if (($default > 0) && (intval(time() - $fileAge) > $default)) { - // $this->logger->info("[Filesystem cache] File too old. Ignoring '$key'"); - // return $default; - // } else { + if (!empty($fileTtl) && time() >= $fileTtl) { + $this->logger->info("[Filesystem cache] File too old. Ignoring '$key'"); + $this->delete($key); + return $default; + } else { $this->logger->info("[Filesystem cache] Get '$key'"); return unserialize(file_get_contents($fileKey)); - // } + } } else { $this->logger->info("[Filesystem cache] Not found '$key'"); return $default; @@ -70,12 +72,20 @@ public function get($key, $default = null) } /** - * @param string $key The object Key - * @param object $value The object to be cached - * @param int $ttl The time to live in seconds of this objects - * @return bool If the object is successfully posted + * Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time. + * + * @param string $key The key of the item to store. + * @param mixed $value The value of the item to store, must be serializable. + * @param null|int|DateInterval $ttl Optional. The TTL value of this item. If no value is sent and + * the driver supports TTL then the library may set a default value + * for it or let the driver take care of that. + * + * @return bool True on success and false on failure. + * + * @throws \Psr\SimpleCache\InvalidArgumentException + * MUST be thrown if the $key string is not a legal value. */ - public function set($key, $value, $ttl = 0) + public function set($key, $value, $ttl = null) { $fileKey = $this->fixKey($key); @@ -84,6 +94,7 @@ public function set($key, $value, $ttl = 0) try { if (file_exists($fileKey)) { unlink($fileKey); + unlink("$fileKey.ttl"); } if (is_null($value)) { @@ -95,6 +106,11 @@ public function set($key, $value, $ttl = 0) } else { file_put_contents($fileKey, serialize($value)); } + + $validUntil = $this->addToNow($ttl); + if (!empty($validUntil)) { + file_put_contents($fileKey . ".ttl", $validUntil); + } } catch (Exception $ex) { $this->logger->warning("[Filesystem cache] I could not write to cache on file '" . basename($key) . "'. Switching to nocache=true mode."); return false; @@ -104,12 +120,13 @@ public function set($key, $value, $ttl = 0) } /** - * Unlock resource * @param string $key + * @return bool */ public function delete($key) { $this->set($key, null); + return true; } /** diff --git a/tests/CachePoolTest.php b/tests/CacheTest.php similarity index 87% rename from tests/CachePoolTest.php rename to tests/CacheTest.php index 792cb35..958a3c4 100644 --- a/tests/CachePoolTest.php +++ b/tests/CacheTest.php @@ -8,7 +8,7 @@ class_alias('\PHPUnit_Framework_TestCase', '\PHPUnit\Framework\TestCase'); } -class CachePoolTest extends \PHPUnit\Framework\TestCase +class CacheTest extends \PHPUnit\Framework\TestCase { /** * @var \ByJG\Cache\Engine\BaseCacheEngine @@ -213,4 +213,34 @@ public function testGetMultipleItemsPsr16(\ByJG\Cache\Engine\BaseCacheEngine $ca $this->markTestIncomplete('Object is not fully functional'); } } + + /** + * @dataProvider CachePoolProvider + * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + */ + public function testTtlPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + { + $this->cacheEngine = $cacheEngine; + + // PSR-6 Test + if ($cacheEngine->isAvailable()) { + // First time + $item = $cacheEngine->get('chave'); + $this->assertEquals(null, $item); + + // Set object + $cacheEngine->set('chave', 'valor', 2); + + // Get Object + if (!($cacheEngine instanceof \ByJG\Cache\Engine\NoCacheEngine)) { + $item2 = $cacheEngine->get('chave'); + $this->assertEquals('valor', $item2); + sleep(3); + $item2 = $cacheEngine->get('chave'); + $this->assertEquals(null, $item2); + } + } else { + $this->markTestIncomplete('Object is not fully functional'); + } + } } From 56c3c6b915d72be35c1b3bdf2a91fb9af2bc1842 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sat, 27 May 2017 12:39:05 -0300 Subject: [PATCH 06/16] Fixed TTL in FileSystemCacheEngine and ShmopCacheEngine --- src/Engine/FileSystemCacheEngine.php | 31 ++++--- src/Engine/ShmopCacheEngine.php | 96 +++++++++++++--------- src/Exception/InvalidArgumentException.php | 14 ++++ tests/CacheTest.php | 7 ++ 4 files changed, 96 insertions(+), 52 deletions(-) create mode 100644 src/Exception/InvalidArgumentException.php diff --git a/src/Engine/FileSystemCacheEngine.php b/src/Engine/FileSystemCacheEngine.php index 03cff3f..7e5ee08 100644 --- a/src/Engine/FileSystemCacheEngine.php +++ b/src/Engine/FileSystemCacheEngine.php @@ -53,18 +53,8 @@ public function get($key, $default = null) // Check if file exists if ($this->has($key)) { - if (file_exists("$fileKey.ttl")) { - $fileTtl = intval(file_get_contents("$fileKey.ttl")); - } - - if (!empty($fileTtl) && time() >= $fileTtl) { - $this->logger->info("[Filesystem cache] File too old. Ignoring '$key'"); - $this->delete($key); - return $default; - } else { - $this->logger->info("[Filesystem cache] Get '$key'"); - return unserialize(file_get_contents($fileKey)); - } + $this->logger->info("[Filesystem cache] Get '$key'"); + return unserialize(file_get_contents($fileKey)); } else { $this->logger->info("[Filesystem cache] Not found '$key'"); return $default; @@ -204,6 +194,21 @@ public function clear() public function has($key) { $fileKey = $this->fixKey($key); - return file_exists($fileKey); + if (file_exists($fileKey)) { + if (file_exists("$fileKey.ttl")) { + $fileTtl = intval(file_get_contents("$fileKey.ttl")); + } + + if (!empty($fileTtl) && time() >= $fileTtl) { + $this->logger->info("[Filesystem cache] File too old. Ignoring '$key'"); + $this->delete($key); + + return false; + } + + return true; + } + + return false; } } diff --git a/src/Engine/ShmopCacheEngine.php b/src/Engine/ShmopCacheEngine.php index 5e26bad..64e0d18 100644 --- a/src/Engine/ShmopCacheEngine.php +++ b/src/Engine/ShmopCacheEngine.php @@ -2,7 +2,7 @@ namespace ByJG\Cache\Engine; -use ByJG\Cache\CacheEngineInterface; +use Psr\Cache\InvalidArgumentException; use Psr\Log\NullLogger; /** @@ -43,7 +43,7 @@ public function __construct($config = [], $logger = null) } } - protected function getFTok($key) + protected function getFilenameToken($key) { return sys_get_temp_dir() . '/shmop-' . sha1($key) . '.cache'; } @@ -58,7 +58,7 @@ protected function getDefaultPermission() return $this->config['default-permission']; } - protected function getKeyId($file) + protected function getFTok($file) { if (!file_exists($file)) { touch($file); @@ -78,8 +78,8 @@ public function get($key, $default = null) return $default; } - $file = $this->getFTok($key); - $fileKey = $this->getKeyId($file); + $file = $this->getFilenameToken($key); + $fileKey = $this->getFTok($file); // Opened $shm_id = @shmop_open($fileKey, "a", 0, 0); @@ -88,21 +88,9 @@ public function get($key, $default = null) return $default; } - // $fileAge = filemtime($this->getFTok($key)); - - // Check @todo TTL - // if (($default > 0) && (intval(time() - $fileAge) > $default)) { - // $this->logger->info("[Shmop Cache] File too old. Ignoring '$key'"); - // - // // Close old descriptor - // shmop_close($shm_id); - // - // // delete old memory segment - // $shm_id = shmop_open($fileKey, "w", $this->getDefaultPermission(), $this->getMaxSize()); - // shmop_delete($shm_id); - // shmop_close($shm_id); - // return $default; - // } + if (!$this->isValidAge($file)) { + return $default; + } $this->logger->info("[Shmop Cache] Get '$key'"); @@ -112,14 +100,33 @@ public function get($key, $default = null) return unserialize($serialized); } + protected function isValidAge($file) + { + if (file_exists("$file.ttl")) { + $fileTtl = intval(file_get_contents("$file.ttl")); + } + + if (!empty($fileTtl) && time() >= $fileTtl) { + $this->logger->info("[Shmop Cache] File too old. Ignoring"); + $this->deleteFromFilenameToken($file); + return false; + } + + return true; + } + /** - * @param string $key The object Key - * @param object $value The object to be cached - * @param int $ttl The time to live in seconds of the object. Depends on implementation. - * @return bool If the object is successfully posted - * @throws \Exception + * Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time. + * + * @param string $key The key of the item to store. + * @param mixed $value The value of the item to store, must be serializable. + * @param null|int|DateInterval $ttl Optional. The TTL value of this item. If no value is sent and + * the driver supports TTL then the library may set a default value + * for it or let the driver take care of that. + * @return bool True on success and false on failure. + * @throws InvalidArgumentException */ - public function set($key, $value, $ttl = 0) + public function set($key, $value, $ttl = null) { $this->logger->info("[Shmop Cache] set '$key'"); @@ -129,11 +136,11 @@ public function set($key, $value, $ttl = 0) $size = strlen($serialized); if ($size > $this->getMaxSize()) { - throw new \Exception('Object is greater than the max size allowed: ' . $this->getMaxSize()); + throw new \ByJG\Cache\InvalidArgumentException('Object is greater than the max size allowed: ' . $this->getMaxSize()); } - $file = $this->getFTok($key); - $shmKey = $this->getKeyId($file); + $file = $this->getFilenameToken($key); + $shmKey = $this->getFTok($file); $shm_id = shmop_open($shmKey, "c", 0777, $size); if (!$shm_id) { $message = "Couldn't create shared memory segment"; @@ -141,7 +148,7 @@ public function set($key, $value, $ttl = 0) if (isset($lastError['message'])) { $message = $lastError['message']; } - throw new \Exception($message); + throw new \ByJG\Cache\InvalidArgumentException($message); } $shm_bytes_written = shmop_write($shm_id, $serialized, 0); @@ -151,12 +158,17 @@ public function set($key, $value, $ttl = 0) } shmop_close($shm_id); + $validUntil = $this->addToNow($ttl); + if (!empty($validUntil)) { + file_put_contents("$file.ttl", $validUntil); + } + return true; } /** - * Release the object * @param string $key + * @return bool */ public function delete($key) { @@ -164,22 +176,27 @@ public function delete($key) if ($this->get($key) === false) { $this->logger->info("[Shmop Cache] release '$key' does not exists."); - return; + return false; } - $file = $this->getFTok($key); - $this->deleteFromFTok($file); + $file = $this->getFilenameToken($key); + $this->deleteFromFilenameToken($file); + return true; } - private function deleteFromFTok($file) + private function deleteFromFilenameToken($file) { - $filekey = $this->getKeyId($file); + $filekey = $this->getFTok($file); $shm_id = @shmop_open($filekey, "w", 0, 0); if (file_exists($file)) { unlink($file); } + if (file_exists("$file.ttl")) { + unlink("$file.ttl"); + } + if ($shm_id) { shmop_delete($shm_id); shmop_close($shm_id); @@ -193,14 +210,14 @@ public function clear() $patternKey = sys_get_temp_dir() . '/shmop-*.cache'; $list = glob($patternKey); foreach ($list as $file) { - $this->deleteFromFTok($file); + $this->deleteFromFilenameToken($file); } } public function has($key) { - $file = $this->getFTok($key); - $fileKey = $this->getKeyId($file); + $file = $this->getFilenameToken($key); + $fileKey = $this->getFTok($file); // Opened $shm_id = @shmop_open($fileKey, "a", 0, 0); @@ -209,6 +226,7 @@ public function has($key) if ($exists) { shmop_close($shm_id); + return $this->isValidAge($file); } return $exists; diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..c4efba1 --- /dev/null +++ b/src/Exception/InvalidArgumentException.php @@ -0,0 +1,14 @@ +get('chave'); $this->assertEquals(null, $item); + $this->assertFalse($cacheEngine->has('chave')); + $item2 = $cacheEngine->get('chave2'); + $this->assertEquals(null, $item2); + $this->assertFalse($cacheEngine->has('chave2')); // Set object $cacheEngine->set('chave', 'valor', 2); + $cacheEngine->set('chave2', 'valor2', 2); // Get Object if (!($cacheEngine instanceof \ByJG\Cache\Engine\NoCacheEngine)) { $item2 = $cacheEngine->get('chave'); $this->assertEquals('valor', $item2); + $this->assertTrue($cacheEngine->has('chave2')); sleep(3); $item2 = $cacheEngine->get('chave'); $this->assertEquals(null, $item2); + $this->assertFalse($cacheEngine->has('chave2')); } } else { $this->markTestIncomplete('Object is not fully functional'); From 67a4571ba6465d013fbe53fc5136d05570aa22fb Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sat, 27 May 2017 12:47:31 -0300 Subject: [PATCH 07/16] Added method for test serialization of objects; --- tests/CacheTest.php | 37 ++++++++++++++++++++++++++ tests/Model.php | 64 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 tests/Model.php diff --git a/tests/CacheTest.php b/tests/CacheTest.php index 6f52496..b49d186 100644 --- a/tests/CacheTest.php +++ b/tests/CacheTest.php @@ -1,7 +1,10 @@ markTestIncomplete('Object is not fully functional'); } } + + /** + * @dataProvider CachePoolProvider + * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + */ + public function testCacheObjectPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + { + $this->cacheEngine = $cacheEngine; + + // PSR-6 Test + if ($cacheEngine->isAvailable()) { + // First time + $item = $cacheEngine->get('chave'); + $this->assertEquals(null, $item); + + // Set object + $model = new Model(10, 20); + $cacheEngine->set('chave', $model); + + // Get Object + if (!($cacheEngine instanceof \ByJG\Cache\Engine\NoCacheEngine)) { + $item2 = $cacheEngine->get('chave'); + $this->assertEquals($model, $item2); + } + + // Delete + $cacheEngine->delete('chave'); + $item = $cacheEngine->get('chave'); + $this->assertEquals(null, $item); + } else { + $this->markTestIncomplete('Object is not fully functional'); + } + } + } diff --git a/tests/Model.php b/tests/Model.php new file mode 100644 index 0000000..8c3becb --- /dev/null +++ b/tests/Model.php @@ -0,0 +1,64 @@ +prop1 = $prop1; + $this->prop2 = $prop2; + } + + /** + * @return mixed + */ + public function getProp1() + { + return $this->prop1; + } + + /** + * @param mixed $prop1 + */ + public function setProp1($prop1) + { + $this->prop1 = $prop1; + } + + /** + * @return mixed + */ + public function getProp2() + { + return $this->prop2; + } + + /** + * @param mixed $prop2 + */ + public function setProp2($prop2) + { + $this->prop2 = $prop2; + } + + public function sum() + { + return $this->prop1 + $this->prop2; + } +} From ecb2f4edccbf7a901907a824d575d66070e4986c Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sat, 27 May 2017 12:53:23 -0300 Subject: [PATCH 08/16] Added method for test PSR-6 TTL; --- tests/CacheTest.php | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/CacheTest.php b/tests/CacheTest.php index b49d186..b42eb32 100644 --- a/tests/CacheTest.php +++ b/tests/CacheTest.php @@ -217,6 +217,47 @@ public function testGetMultipleItemsPsr16(\ByJG\Cache\Engine\BaseCacheEngine $ca } } + /** + * @dataProvider CachePoolProvider + * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + */ + public function testTtlPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + { + $this->cacheEngine = $cacheEngine; + + // PSR-6 Test + $object = new CachePool($cacheEngine); + if ($object->isAvailable()) { + // First time + $item = $object->getItem('chave'); + $this->assertFalse($item->isHit()); + + // Set object + $item->set('valor'); + $item->expiresAfter(2); + $object->save($item); + $this->assertTrue($item->isHit()); + + // Get Object + $item2 = $object->getItem('chave'); + $this->assertTrue($item2->isHit()); + $this->assertEquals('valor', $item2->get()); + sleep(3); + $item3 = $object->getItem('chave'); + $this->assertFalse($item3->isHit()); + $this->assertEquals(null, $item3->get()); + + // Remove + $object->deleteItem('chave'); + + // Check Removed + $item = $object->getItem('chave'); + $this->assertFalse($item->isHit()); + } else { + $this->markTestIncomplete('Object is not fully functional'); + } + } + /** * @dataProvider CachePoolProvider * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine From 1d97d34d3fde42277653802a3588670a035710be Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sat, 27 May 2017 12:59:02 -0300 Subject: [PATCH 09/16] Fixed TTL in ArrayCacheEngine --- src/Engine/ArrayCacheEngine.php | 43 +++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/Engine/ArrayCacheEngine.php b/src/Engine/ArrayCacheEngine.php index ec5779d..480b361 100644 --- a/src/Engine/ArrayCacheEngine.php +++ b/src/Engine/ArrayCacheEngine.php @@ -21,12 +21,29 @@ public function __construct($logger = null) } /** - * @param string $key + * Determines whether an item is present in the cache. + * NOTE: It is recommended that has() is only to be used for cache warming type purposes + * and not to be used within your live applications operations for get/set, as this method + * is subject to a race condition where your has() will return true and immediately after, + * another script can remove it making the state of your app out of date. + * + * @param string $key The cache item key. * @return bool + * @throws \Psr\SimpleCache\InvalidArgumentException + * MUST be thrown if the $key string is not a legal value. */ public function has($key) { - return isset($this->cache[$key]); + if (isset($this->cache[$key])) { + if (isset($this->cache["$key.ttl"]) && time() >= $this->cache["$key.ttl"]) { + $this->delete($key); + return false; + } + + return true; + } + + return false; } /** @@ -46,16 +63,27 @@ public function get($key, $default = null) } /** - * @param string $key The object Key - * @param object $value The object to be cached - * @param int $ttl The time to live in seconds of this objects - * @return bool If the object is successfully posted + * Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time. + * + * @param string $key The key of the item to store. + * @param mixed $value The value of the item to store, must be serializable. + * @param null|int|DateInterval $ttl Optional. The TTL value of this item. If no value is sent and + * the driver supports TTL then the library may set a default value + * for it or let the driver take care of that. + * + * @return bool True on success and false on failure. + * + * @throws \Psr\SimpleCache\InvalidArgumentException + * MUST be thrown if the $key string is not a legal value. */ - public function set($key, $value, $ttl = 0) + public function set($key, $value, $ttl = null) { $this->logger->info("[Array cache] Set '$key' in L1 Cache"); $this->cache[$key] = $value; + if (!empty($ttl)) { + $this->cache["$key.ttl"] = $this->addToNow($ttl); + } return true; } @@ -74,6 +102,7 @@ public function clear() public function delete($key) { unset($this->cache[$key]); + unset($this->cache["$key.ttl"]); return true; } From b133fae8f0085c2caa623edb960efdd4cb8a99ac Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sat, 27 May 2017 13:03:05 -0300 Subject: [PATCH 10/16] Fixed TTL in SessionCacheEngine --- src/Engine/SessionCacheEngine.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Engine/SessionCacheEngine.php b/src/Engine/SessionCacheEngine.php index 278536d..9990286 100644 --- a/src/Engine/SessionCacheEngine.php +++ b/src/Engine/SessionCacheEngine.php @@ -36,7 +36,7 @@ public function get($key, $default = null) $keyName = $this->keyName($key); - if (isset($_SESSION[$keyName])) { + if ($this->has($key)) { return $_SESSION[$keyName]; } else { return $default; @@ -52,14 +52,20 @@ public function delete($key) if (isset($_SESSION[$keyName])) { unset($_SESSION[$keyName]); } + if (isset($_SESSION["$keyName.ttl"])) { + unset($_SESSION["$keyName.ttl"]); + } } - public function set($key, $value, $ttl = 0) + public function set($key, $value, $ttl = null) { $this->checkSession(); $keyName = $this->keyName($key); $_SESSION[$keyName] = $value; + if (!empty($ttl)) { + $_SESSION["$keyName.ttl"] = $this->addToNow($ttl); + } } public function clear() @@ -71,7 +77,16 @@ public function has($key) { $keyName = $this->keyName($key); - return (isset($_SESSION[$keyName])); + if (isset($_SESSION[$keyName])) { + if (isset($_SESSION["$keyName.ttl"]) && time() >= $_SESSION["$keyName.ttl"]) { + $this->delete($key); + return false; + } + + return true; + } + + return false; } public function isAvailable() From 8f9b08322fc107386a84f389851b96382813ca6b Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sat, 27 May 2017 14:25:26 -0300 Subject: [PATCH 11/16] Adapted Memcached with the new PSR-16 Interface --- src/Engine/MemcachedEngine.php | 79 ++++++++++++++-------------------- tests/CacheTest.php | 8 ++-- 2 files changed, 37 insertions(+), 50 deletions(-) diff --git a/src/Engine/MemcachedEngine.php b/src/Engine/MemcachedEngine.php index 4052c55..421d3b5 100644 --- a/src/Engine/MemcachedEngine.php +++ b/src/Engine/MemcachedEngine.php @@ -6,7 +6,7 @@ use Memcached; use Psr\Log\NullLogger; -class MemcachedEngine implements CacheEngineInterface +class MemcachedEngine extends BaseCacheEngine { /** @@ -34,6 +34,10 @@ public function __construct($servers = null, $logger = null) } } + protected function fixKey($key) { + return "cache-" . $key; + } + protected function lazyLoadMemCachedServers() { if (is_null($this->memCached)) { @@ -53,19 +57,19 @@ protected function lazyLoadMemCachedServers() /** * @param string $key The object KEY * @param int $default IGNORED IN MEMCACHED. - * @return object Description + * @return mixed Description */ - public function get($key, $default = 0) + public function get($key, $default = null) { $this->lazyLoadMemCachedServers(); - $value = $this->memCached->get($key); + $value = $this->memCached->get($this->fixKey($key)); if ($this->memCached->getResultCode() !== Memcached::RES_SUCCESS) { $this->logger->info("[Memcached] Cache '$key' missed with status " . $this->memCached->getResultCode()); - return null; + return $default; } - return $value; + return unserialize($value); } /** @@ -74,11 +78,11 @@ public function get($key, $default = 0) * @param int $ttl The time to live in seconds of this objects * @return bool If the object is successfully posted */ - public function set($key, $value, $ttl = 0) + public function set($key, $value, $ttl = null) { $this->lazyLoadMemCachedServers(); - $this->memCached->set($key, $value, $ttl); + $this->memCached->set($this->fixKey($key), serialize($value), $ttl); $this->logger->info("[Memcached] Set '$key' result " . $this->memCached->getResultCode()); if ($this->memCached->getResultCode() !== Memcached::RES_SUCCESS) { $this->logger->error("[Memcached] Set '$key' failed with status " . $this->memCached->getResultCode()); @@ -88,50 +92,15 @@ public function set($key, $value, $ttl = 0) } /** - * Unlock resource - * @param string $key - */ - public function delete($key) - { - $this->lazyLoadMemCachedServers(); - - $this->memCached->delete($key); - } - - /** - * * @param string $key - * @param string $str * @return bool */ - public function append($key, $str) - { - $this->lazyLoadMemCachedServers(); - - $this->logger->info("[Memcached] Append '$key' in Memcached"); - return $this->memCached->append($key, $str); - } - - /** - * Lock resource before set it. - * @param string $key - */ - public function lock($key) - { - $this->lazyLoadMemCachedServers(); - - return; - } - - /** - * UnLock resource after set it - * @param string $key - */ - public function unlock($key) + public function delete($key) { $this->lazyLoadMemCachedServers(); - return; + $this->memCached->delete($this->fixKey($key)); + return true; } public function isAvailable() @@ -147,4 +116,22 @@ public function isAvailable() return false; } } + + public function clear() + { + $keys = $this->memCached->getAllKeys(); + foreach ((array)$keys as $key) { + if (preg_match('/^cache-(?.*?)/', $key, $matches)) { + $this->delete($matches['key']); + } + } + } + + public function has($key) + { + $this->lazyLoadMemCachedServers(); + + $this->memCached->get($this->fixKey($key)); + return ($this->memCached->getResultCode() === Memcached::RES_SUCCESS); + } } diff --git a/tests/CacheTest.php b/tests/CacheTest.php index b42eb32..dd378a2 100644 --- a/tests/CacheTest.php +++ b/tests/CacheTest.php @@ -51,10 +51,10 @@ public function CachePoolProvider() 'NoCacheEngine' => [ new \ByJG\Cache\Engine\NoCacheEngine() ], - // [ - // new \ByJG\Cache\Engine\MemcachedEngine($memcachedServer) - // ], - // [ + 'Memcached' => [ + new \ByJG\Cache\Engine\MemcachedEngine($memcachedServer) + ], + // 'Redis' => [ // new \ByJG\Cache\Engine\RedisCacheEngine($redisCacheServer, $redisPassword) // ] ]; From 74236dc1099040791b00910361d2ab69f195553c Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sat, 27 May 2017 15:29:19 -0300 Subject: [PATCH 12/16] Fix RedisCacheEngine and Reorganize tests. --- src/Engine/BaseCacheEngine.php | 4 + src/Engine/MemcachedEngine.php | 8 +- src/Engine/RedisCacheEngine.php | 62 ++---- tests/BaseCacheTest.php | 62 ++++++ tests/{CacheTest.php => CachePSR16Test.php} | 222 ++++---------------- tests/CachePSR6Test.php | 131 ++++++++++++ 6 files changed, 265 insertions(+), 224 deletions(-) create mode 100644 tests/BaseCacheTest.php rename tests/{CacheTest.php => CachePSR16Test.php} (51%) create mode 100644 tests/CachePSR6Test.php diff --git a/src/Engine/BaseCacheEngine.php b/src/Engine/BaseCacheEngine.php index b8c8dd6..c3d69f2 100644 --- a/src/Engine/BaseCacheEngine.php +++ b/src/Engine/BaseCacheEngine.php @@ -3,12 +3,16 @@ namespace ByJG\Cache\Engine; use ByJG\Cache\CacheAvailabilityInterface; +use ByJG\Cache\InvalidArgumentException; use Psr\SimpleCache\CacheInterface; abstract class BaseCacheEngine implements CacheInterface, CacheAvailabilityInterface { public function getMultiple($keys, $default = null) { + if (!is_array($keys)) { + throw new InvalidArgumentException('getMultipleKeys expected an array'); + } $result = []; foreach ($keys as $key) { $result[$key] = $this->get($key, $default); diff --git a/src/Engine/MemcachedEngine.php b/src/Engine/MemcachedEngine.php index 421d3b5..b013711 100644 --- a/src/Engine/MemcachedEngine.php +++ b/src/Engine/MemcachedEngine.php @@ -119,12 +119,8 @@ public function isAvailable() public function clear() { - $keys = $this->memCached->getAllKeys(); - foreach ((array)$keys as $key) { - if (preg_match('/^cache-(?.*?)/', $key, $matches)) { - $this->delete($matches['key']); - } - } + $result = $this->memCached->flush(); + return $result; } public function has($key) diff --git a/src/Engine/RedisCacheEngine.php b/src/Engine/RedisCacheEngine.php index f962a3f..d167812 100644 --- a/src/Engine/RedisCacheEngine.php +++ b/src/Engine/RedisCacheEngine.php @@ -2,10 +2,9 @@ namespace ByJG\Cache\Engine; -use ByJG\Cache\CacheEngineInterface; use Psr\Log\NullLogger; -class RedisCacheEngine implements CacheEngineInterface +class RedisCacheEngine extends BaseCacheEngine { /** @@ -51,19 +50,23 @@ protected function lazyLoadRedisServer() } } + protected function fixKey($key) { + return "cache:$key"; + } + /** * @param string $key The object KEY * @param int $default IGNORED IN MEMCACHED. * @return object Description */ - public function get($key, $default = 0) + public function get($key, $default = null) { $this->lazyLoadRedisServer(); - $value = $this->redis->get($key); + $value = $this->redis->get($this->fixKey($key)); $this->logger->info("[Redis Cache] Get '$key' result "); - return ($value === false ? null : $value); + return ($value === false ? $default : unserialize($value)); } /** @@ -72,61 +75,38 @@ public function get($key, $default = 0) * @param int $ttl The time to live in seconds of this objects * @return bool If the object is successfully posted */ - public function set($key, $value, $ttl = 0) + public function set($key, $value, $ttl = null) { $this->lazyLoadRedisServer(); - $this->redis->set($key, $value, $ttl); + $this->redis->set($this->fixKey($key), serialize($value), $ttl); $this->logger->info("[Redis Cache] Set '$key' result "); return true; } - /** - * Unlock resource - * @param string $key - */ public function delete($key) { $this->lazyLoadRedisServer(); - $this->redis->delete($key); - } - - /** - * - * @param string $key - * @param string $str - * @return bool - */ - public function append($key, $str) - { - $this->lazyLoadRedisServer(); + $this->redis->delete($this->fixKey($key)); - $this->logger->info("[Redis Cache] Append '$key' in Memcached"); - return $this->redis->append($key, $str); + return true; } - /** - * Lock resource before set it. - * @param string $key - */ - public function lock($key) + public function clear() { - $this->lazyLoadRedisServer(); - - return; + $keys = $this->redis->keys('cache:*'); + foreach ((array)$keys as $key) { + if (preg_match('/^cache\:(?.*)/', $key, $matches)) { + $this->delete($matches['key']); + } + } } - /** - * UnLock resource after set it - * @param string $key - */ - public function unlock($key) + public function has($key) { - $this->lazyLoadRedisServer(); - - return; + return $this->redis->exists($this->fixKey($key)); } public function isAvailable() diff --git a/tests/BaseCacheTest.php b/tests/BaseCacheTest.php new file mode 100644 index 0000000..88be89d --- /dev/null +++ b/tests/BaseCacheTest.php @@ -0,0 +1,62 @@ +cacheEngine->clear(); + $this->cacheEngine = null; + } + + public function CachePoolProvider() + { + $memcachedServer = ['memcached-container:11211']; + $redisCacheServer = 'redis-container:6379'; + $redisPassword = ''; + + return [ + 'Array' => [ + new \ByJG\Cache\Engine\ArrayCacheEngine() + ], + 'FileSystem' => [ + new \ByJG\Cache\Engine\FileSystemCacheEngine() + ], + 'ShmopCache' => [ + new \ByJG\Cache\Engine\ShmopCacheEngine() + ], + 'SessionCache' => [ + new \ByJG\Cache\Engine\SessionCacheEngine() + ], + 'NoCacheEngine' => [ + new \ByJG\Cache\Engine\NoCacheEngine() + ], + 'Memcached' => [ + new \ByJG\Cache\Engine\MemcachedEngine($memcachedServer) + ], + 'Redis' => [ + new \ByJG\Cache\Engine\RedisCacheEngine($redisCacheServer, $redisPassword) + ] + ]; + } +} diff --git a/tests/CacheTest.php b/tests/CachePSR16Test.php similarity index 51% rename from tests/CacheTest.php rename to tests/CachePSR16Test.php index dd378a2..f3051f9 100644 --- a/tests/CacheTest.php +++ b/tests/CachePSR16Test.php @@ -2,144 +2,12 @@ namespace Test; -use ByJG\Cache\Psr6\CachePool; +use ByJG\Cache\Engine\NoCacheEngine; -require_once 'Model.php'; +require_once 'BaseCacheTest.php'; -// backward compatibility -if (!class_exists('\PHPUnit\Framework\TestCase')) { - class_alias('\PHPUnit_Framework_TestCase', '\PHPUnit\Framework\TestCase'); -} - -class CacheTest extends \PHPUnit\Framework\TestCase +class CachePSR16Test extends BaseCacheTest { - /** - * @var \ByJG\Cache\Engine\BaseCacheEngine - */ - private $cacheEngine = null; - - protected function setUp() - { - - } - - protected function tearDown() - { - $this->cacheEngine->clear(); - $this->cacheEngine = null; - } - - public function CachePoolProvider() - { - $memcachedServer = ['memcached-container:11211']; - $redisCacheServer = 'redis-container:6379'; - $redisPassword = ''; - - return [ - 'Array' => [ - new \ByJG\Cache\Engine\ArrayCacheEngine() - ], - 'FileSystem' => [ - new \ByJG\Cache\Engine\FileSystemCacheEngine() - ], - 'ShmopCache' => [ - new \ByJG\Cache\Engine\ShmopCacheEngine() - ], - 'SessionCache' => [ - new \ByJG\Cache\Engine\SessionCacheEngine() - ], - 'NoCacheEngine' => [ - new \ByJG\Cache\Engine\NoCacheEngine() - ], - 'Memcached' => [ - new \ByJG\Cache\Engine\MemcachedEngine($memcachedServer) - ], - // 'Redis' => [ - // new \ByJG\Cache\Engine\RedisCacheEngine($redisCacheServer, $redisPassword) - // ] - ]; - } - - /** - * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine - */ - public function testGetOneItemPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) - { - $this->cacheEngine = $cacheEngine; - - // PSR-6 Test - $object = new CachePool($cacheEngine); - if ($object->isAvailable()) { - // First time - $item = $object->getItem('chave'); - $this->assertFalse($item->isHit()); - - // Set object - $item->set('valor'); - $object->save($item); - $this->assertTrue($item->isHit()); - - // Get Object - $item2 = $object->getItem('chave'); - $this->assertTrue($item2->isHit()); - $this->assertEquals('valor', $item2->get()); - - // Remove - $object->deleteItem('chave'); - - // Check Removed - $item = $object->getItem('chave'); - $this->assertFalse($item->isHit()); - } else { - $this->markTestIncomplete('Object is not fully functional'); - } - } - - /** - * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine - */ - public function testGetMultipleItemsPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) - { - $this->cacheEngine = $cacheEngine; - - // PSR-6 Test - $object = new CachePool($cacheEngine); - if ($object->isAvailable()) { - // First time - $items = $object->getItems(['chave1', 'chave2']); - $this->assertFalse($items[0]->isHit()); - $this->assertFalse($items[1]->isHit()); - - // Set object - $items[0]->set('valor1'); - $items[1]->set('valor2'); - $object->saveDeferred($items[0]); - $object->saveDeferred($items[1]); - $object->commit(); - $this->assertTrue($items[0]->isHit()); - $this->assertTrue($items[1]->isHit()); - - // Get Object - $item2 = $object->getItems(['chave1', 'chave2']); - $this->assertTrue($item2[0]->isHit()); - $this->assertTrue($item2[1]->isHit()); - $this->assertEquals('valor1', $item2[0]->get()); - $this->assertEquals('valor2', $item2[1]->get()); - - // Remove - $object->deleteItems(['chave1', 'chave2']); - - // Check Removed - $items = $object->getItems(['chave1', 'chave2']); - $this->assertFalse($items[0]->isHit()); - $this->assertFalse($items[1]->isHit()); - } else { - $this->markTestIncomplete('Object is not fully functional'); - } - } - /** * @dataProvider CachePoolProvider * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine @@ -217,47 +85,6 @@ public function testGetMultipleItemsPsr16(\ByJG\Cache\Engine\BaseCacheEngine $ca } } - /** - * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine - */ - public function testTtlPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) - { - $this->cacheEngine = $cacheEngine; - - // PSR-6 Test - $object = new CachePool($cacheEngine); - if ($object->isAvailable()) { - // First time - $item = $object->getItem('chave'); - $this->assertFalse($item->isHit()); - - // Set object - $item->set('valor'); - $item->expiresAfter(2); - $object->save($item); - $this->assertTrue($item->isHit()); - - // Get Object - $item2 = $object->getItem('chave'); - $this->assertTrue($item2->isHit()); - $this->assertEquals('valor', $item2->get()); - sleep(3); - $item3 = $object->getItem('chave'); - $this->assertFalse($item3->isHit()); - $this->assertEquals(null, $item3->get()); - - // Remove - $object->deleteItem('chave'); - - // Check Removed - $item = $object->getItem('chave'); - $this->assertFalse($item->isHit()); - } else { - $this->markTestIncomplete('Object is not fully functional'); - } - } - /** * @dataProvider CachePoolProvider * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine @@ -303,7 +130,7 @@ public function testCacheObjectPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEn { $this->cacheEngine = $cacheEngine; - // PSR-6 Test + // PSR-16 Test if ($cacheEngine->isAvailable()) { // First time $item = $cacheEngine->get('chave'); @@ -328,4 +155,45 @@ public function testCacheObjectPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEn } } + /** + * @dataProvider CachePoolProvider + * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + */ + public function testClearPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + { + $this->cacheEngine = $cacheEngine; + + // PSR-16 Test + if ($cacheEngine->isAvailable()) { + // Values + $empty = [ + 'chave' => null, + 'chave2' => null, + 'chave3' => null + ]; + $set = [ + 'chave' => 'val', + 'chave2' => 'val2', + 'chave3' => 'val3' + ]; + + // First time + $item = $cacheEngine->getMultiple(['chave', 'chave2', 'chave3']); + $this->assertEquals($empty, $item); + + // Set and Check + $cacheEngine->setMultiple($set); + if (!($cacheEngine instanceof NoCacheEngine)) { + $item = $cacheEngine->getMultiple(['chave', 'chave2', 'chave3']); + $this->assertEquals($set, $item); + } + + // Clear and Check + $cacheEngine->clear(); + $item = $cacheEngine->getMultiple(['chave', 'chave2', 'chave3']); + $this->assertEquals($empty, $item); + } else { + $this->markTestIncomplete('Object is not fully functional'); + } + } } diff --git a/tests/CachePSR6Test.php b/tests/CachePSR6Test.php new file mode 100644 index 0000000..ef59ac1 --- /dev/null +++ b/tests/CachePSR6Test.php @@ -0,0 +1,131 @@ +cacheEngine = $cacheEngine; + + // PSR-6 Test + $object = new CachePool($cacheEngine); + if ($object->isAvailable()) { + // First time + $item = $object->getItem('chave'); + $this->assertFalse($item->isHit()); + + // Set object + $item->set('valor'); + $object->save($item); + $this->assertTrue($item->isHit()); + + // Get Object + $item2 = $object->getItem('chave'); + $this->assertTrue($item2->isHit()); + $this->assertEquals('valor', $item2->get()); + + // Remove + $object->deleteItem('chave'); + + // Check Removed + $item = $object->getItem('chave'); + $this->assertFalse($item->isHit()); + } else { + $this->markTestIncomplete('Object is not fully functional'); + } + } + + /** + * @dataProvider CachePoolProvider + * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + */ + public function testGetMultipleItemsPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + { + $this->cacheEngine = $cacheEngine; + + // PSR-6 Test + $object = new CachePool($cacheEngine); + if ($object->isAvailable()) { + // First time + $items = $object->getItems(['chave1', 'chave2']); + $this->assertFalse($items[0]->isHit()); + $this->assertFalse($items[1]->isHit()); + + // Set object + $items[0]->set('valor1'); + $items[1]->set('valor2'); + $object->saveDeferred($items[0]); + $object->saveDeferred($items[1]); + $object->commit(); + $this->assertTrue($items[0]->isHit()); + $this->assertTrue($items[1]->isHit()); + + // Get Object + $item2 = $object->getItems(['chave1', 'chave2']); + $this->assertTrue($item2[0]->isHit()); + $this->assertTrue($item2[1]->isHit()); + $this->assertEquals('valor1', $item2[0]->get()); + $this->assertEquals('valor2', $item2[1]->get()); + + // Remove + $object->deleteItems(['chave1', 'chave2']); + + // Check Removed + $items = $object->getItems(['chave1', 'chave2']); + $this->assertFalse($items[0]->isHit()); + $this->assertFalse($items[1]->isHit()); + } else { + $this->markTestIncomplete('Object is not fully functional'); + } + } + + /** + * @dataProvider CachePoolProvider + * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + */ + public function testTtlPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + { + $this->cacheEngine = $cacheEngine; + + // PSR-6 Test + $object = new CachePool($cacheEngine); + if ($object->isAvailable()) { + // First time + $item = $object->getItem('chave'); + $this->assertFalse($item->isHit()); + + // Set object + $item->set('valor'); + $item->expiresAfter(2); + $object->save($item); + $this->assertTrue($item->isHit()); + + // Get Object + $item2 = $object->getItem('chave'); + $this->assertTrue($item2->isHit()); + $this->assertEquals('valor', $item2->get()); + sleep(3); + $item3 = $object->getItem('chave'); + $this->assertFalse($item3->isHit()); + $this->assertEquals(null, $item3->get()); + + // Remove + $object->deleteItem('chave'); + + // Check Removed + $item = $object->getItem('chave'); + $this->assertFalse($item->isHit()); + } else { + $this->markTestIncomplete('Object is not fully functional'); + } + } +} From bf676536b92dad45551d8b0dee64e2a9b1410951 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sat, 27 May 2017 15:43:31 -0300 Subject: [PATCH 13/16] Renamed the namespace ByJG\Cache\Engine to ByJG\Cache\Psr16 --- README.md | 18 +++---- src/Factory.php | 14 ++--- src/{Engine => Psr16}/ArrayCacheEngine.php | 2 +- src/{Engine => Psr16}/BaseCacheEngine.php | 2 +- .../FileSystemCacheEngine.php | 2 +- src/{Engine => Psr16}/MemcachedEngine.php | 2 +- src/{Engine => Psr16}/NoCacheEngine.php | 2 +- src/{Engine => Psr16}/RedisCacheEngine.php | 2 +- src/{Engine => Psr16}/SessionCacheEngine.php | 2 +- src/{Engine => Psr16}/ShmopCacheEngine.php | 2 +- src/Psr6/CachePool.php | 2 +- tests/BaseCacheTest.php | 16 +++--- tests/CachePSR16Test.php | 35 ++++++------- tests/CachePSR6Test.php | 51 +++++++++++++++---- 14 files changed, 90 insertions(+), 62 deletions(-) rename src/{Engine => Psr16}/ArrayCacheEngine.php (99%) rename src/{Engine => Psr16}/BaseCacheEngine.php (97%) rename src/{Engine => Psr16}/FileSystemCacheEngine.php (99%) rename src/{Engine => Psr16}/MemcachedEngine.php (99%) rename src/{Engine => Psr16}/NoCacheEngine.php (98%) rename src/{Engine => Psr16}/RedisCacheEngine.php (99%) rename src/{Engine => Psr16}/SessionCacheEngine.php (98%) rename src/{Engine => Psr16}/ShmopCacheEngine.php (99%) diff --git a/README.md b/README.md index 10cb04c..8282e1f 100644 --- a/README.md +++ b/README.md @@ -13,20 +13,20 @@ A multi-purpose cache engine PSR-6 and PSR-16 implementation with several driver PSR-16 defines a Simple Cache interface with less verbosity than PSR-6. Below a list of engines available in this library that is PSR-16 compliant: -| Class | Description | -|:----------------------------------|:--------------------------------------------------------------------| -| \ByJG\Cache\NoCacheEngine | Do nothing. Use it for disable the cache without change your code | -| \ByJG\Cache\ArrayCacheEngine | Local cache only using array. It does not persists between requests | -| \ByJG\Cache\FileSystemCacheEngine | Save the cache result in the local file system | -| \ByJG\Cache\MemcachedEngine | Uses the Memcached as the cache engine | -| \ByJG\Cache\SessionCachedEngine | uses the PHP session as cache | -| \ByJG\Cache\ShmopCachedEngine | uses the shared memory area for cache | +| Class | Description | +|:----------------------------------------|:--------------------------------------------------------------------| +| \ByJG\Cache\Psr16\NoCacheEngine | Do nothing. Use it for disable the cache without change your code | +| \ByJG\Cache\Psr16\ArrayCacheEngine | Local cache only using array. It does not persists between requests | +| \ByJG\Cache\Psr16\FileSystemCacheEngine | Save the cache result in the local file system | +| \ByJG\Cache\Psr16\MemcachedEngine | Uses the Memcached as the cache engine | +| \ByJG\Cache\Psr16\SessionCachedEngine | uses the PHP session as cache | +| \ByJG\Cache\Psr16\ShmopCachedEngine | uses the shared memory area for cache | To create a new Cache Instance just create the proper cache engine and use it: ```php get('key'); diff --git a/src/Factory.php b/src/Factory.php index 0643816..c62f989 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -2,13 +2,13 @@ namespace ByJG\Cache; -use ByJG\Cache\Engine\ArrayCacheEngine; -use ByJG\Cache\Engine\FileSystemCacheEngine; -use ByJG\Cache\Engine\MemcachedEngine; -use ByJG\Cache\Engine\NoCacheEngine; -use ByJG\Cache\Engine\RedisCacheEngine; -use ByJG\Cache\Engine\SessionCacheEngine; -use ByJG\Cache\Engine\ShmopCacheEngine; +use ByJG\Cache\Psr16\ArrayCacheEngine; +use ByJG\Cache\Psr16\FileSystemCacheEngine; +use ByJG\Cache\Psr16\MemcachedEngine; +use ByJG\Cache\Psr16\NoCacheEngine; +use ByJG\Cache\Psr16\RedisCacheEngine; +use ByJG\Cache\Psr16\SessionCacheEngine; +use ByJG\Cache\Psr16\ShmopCacheEngine; use ByJG\Cache\Psr\CachePool; class Factory diff --git a/src/Engine/ArrayCacheEngine.php b/src/Psr16/ArrayCacheEngine.php similarity index 99% rename from src/Engine/ArrayCacheEngine.php rename to src/Psr16/ArrayCacheEngine.php index 480b361..d0482ad 100644 --- a/src/Engine/ArrayCacheEngine.php +++ b/src/Psr16/ArrayCacheEngine.php @@ -1,6 +1,6 @@ [ - new \ByJG\Cache\Engine\ArrayCacheEngine() + new \ByJG\Cache\Psr16\ArrayCacheEngine() ], 'FileSystem' => [ - new \ByJG\Cache\Engine\FileSystemCacheEngine() + new \ByJG\Cache\Psr16\FileSystemCacheEngine() ], 'ShmopCache' => [ - new \ByJG\Cache\Engine\ShmopCacheEngine() + new \ByJG\Cache\Psr16\ShmopCacheEngine() ], 'SessionCache' => [ - new \ByJG\Cache\Engine\SessionCacheEngine() + new \ByJG\Cache\Psr16\SessionCacheEngine() ], 'NoCacheEngine' => [ - new \ByJG\Cache\Engine\NoCacheEngine() + new \ByJG\Cache\Psr16\NoCacheEngine() ], 'Memcached' => [ - new \ByJG\Cache\Engine\MemcachedEngine($memcachedServer) + new \ByJG\Cache\Psr16\MemcachedEngine($memcachedServer) ], 'Redis' => [ - new \ByJG\Cache\Engine\RedisCacheEngine($redisCacheServer, $redisPassword) + new \ByJG\Cache\Psr16\RedisCacheEngine($redisCacheServer, $redisPassword) ] ]; } diff --git a/tests/CachePSR16Test.php b/tests/CachePSR16Test.php index f3051f9..a28b5f1 100644 --- a/tests/CachePSR16Test.php +++ b/tests/CachePSR16Test.php @@ -2,7 +2,7 @@ namespace Test; -use ByJG\Cache\Engine\NoCacheEngine; +use ByJG\Cache\Psr16\NoCacheEngine; require_once 'BaseCacheTest.php'; @@ -10,13 +10,12 @@ class CachePSR16Test extends BaseCacheTest { /** * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + * @param \ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine */ - public function testGetOneItemPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + public function testGetOneItem(\ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine) { $this->cacheEngine = $cacheEngine; - // PSR-6 Test if ($cacheEngine->isAvailable()) { // First time $item = $cacheEngine->get('chave', null); @@ -28,7 +27,7 @@ public function testGetOneItemPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEng $cacheEngine->set('chave', 'valor'); // Get Object - if (!($cacheEngine instanceof \ByJG\Cache\Engine\NoCacheEngine)) { + if (!($cacheEngine instanceof \ByJG\Cache\Psr16\NoCacheEngine)) { $item2 = $cacheEngine->get('chave', 'default'); $this->assertEquals('valor', $item2); } @@ -46,13 +45,12 @@ public function testGetOneItemPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEng /** * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + * @param \ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine */ - public function testGetMultipleItemsPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + public function testGetMultipleItems(\ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine) { $this->cacheEngine = $cacheEngine; - // PSR-6 Test if ($cacheEngine->isAvailable()) { // First time $items = $cacheEngine->getMultiple(['chave1', 'chave2']); @@ -67,7 +65,7 @@ public function testGetMultipleItemsPsr16(\ByJG\Cache\Engine\BaseCacheEngine $ca $cacheEngine->set('chave2', 'valor2'); // Get Object - if (!($cacheEngine instanceof \ByJG\Cache\Engine\NoCacheEngine)) { + if (!($cacheEngine instanceof \ByJG\Cache\Psr16\NoCacheEngine)) { $item2 = $cacheEngine->getMultiple(['chave1', 'chave2']); $this->assertEquals('valor1', $item2['chave1']); $this->assertEquals('valor2', $item2['chave2']); @@ -87,13 +85,12 @@ public function testGetMultipleItemsPsr16(\ByJG\Cache\Engine\BaseCacheEngine $ca /** * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + * @param \ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine */ - public function testTtlPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + public function testTtl(\ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine) { $this->cacheEngine = $cacheEngine; - // PSR-6 Test if ($cacheEngine->isAvailable()) { // First time $item = $cacheEngine->get('chave'); @@ -108,7 +105,7 @@ public function testTtlPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) $cacheEngine->set('chave2', 'valor2', 2); // Get Object - if (!($cacheEngine instanceof \ByJG\Cache\Engine\NoCacheEngine)) { + if (!($cacheEngine instanceof \ByJG\Cache\Psr16\NoCacheEngine)) { $item2 = $cacheEngine->get('chave'); $this->assertEquals('valor', $item2); $this->assertTrue($cacheEngine->has('chave2')); @@ -124,13 +121,12 @@ public function testTtlPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) /** * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + * @param \ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine */ - public function testCacheObjectPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + public function testCacheObject(\ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine) { $this->cacheEngine = $cacheEngine; - // PSR-16 Test if ($cacheEngine->isAvailable()) { // First time $item = $cacheEngine->get('chave'); @@ -141,7 +137,7 @@ public function testCacheObjectPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEn $cacheEngine->set('chave', $model); // Get Object - if (!($cacheEngine instanceof \ByJG\Cache\Engine\NoCacheEngine)) { + if (!($cacheEngine instanceof \ByJG\Cache\Psr16\NoCacheEngine)) { $item2 = $cacheEngine->get('chave'); $this->assertEquals($model, $item2); } @@ -157,13 +153,12 @@ public function testCacheObjectPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEn /** * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + * @param \ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine */ - public function testClearPsr16(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + public function testClear(\ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine) { $this->cacheEngine = $cacheEngine; - // PSR-16 Test if ($cacheEngine->isAvailable()) { // Values $empty = [ diff --git a/tests/CachePSR6Test.php b/tests/CachePSR6Test.php index ef59ac1..aa956ab 100644 --- a/tests/CachePSR6Test.php +++ b/tests/CachePSR6Test.php @@ -10,13 +10,12 @@ class CachePSR6Test extends BaseCacheTest { /** * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + * @param \ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine */ - public function testGetOneItemPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + public function testGetOneItem(\ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine) { $this->cacheEngine = $cacheEngine; - // PSR-6 Test $object = new CachePool($cacheEngine); if ($object->isAvailable()) { // First time @@ -46,13 +45,12 @@ public function testGetOneItemPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngi /** * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + * @param \ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine */ - public function testGetMultipleItemsPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + public function testGetMultipleItems(\ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine) { $this->cacheEngine = $cacheEngine; - // PSR-6 Test $object = new CachePool($cacheEngine); if ($object->isAvailable()) { // First time @@ -90,13 +88,12 @@ public function testGetMultipleItemsPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cac /** * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Engine\BaseCacheEngine $cacheEngine + * @param \ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine */ - public function testTtlPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) + public function testTtl(\ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine) { $this->cacheEngine = $cacheEngine; - // PSR-6 Test $object = new CachePool($cacheEngine); if ($object->isAvailable()) { // First time @@ -128,4 +125,40 @@ public function testTtlPsr6(\ByJG\Cache\Engine\BaseCacheEngine $cacheEngine) $this->markTestIncomplete('Object is not fully functional'); } } + + /** + * @dataProvider CachePoolProvider + * @param \ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine + */ + public function testCacheObject(\ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine) + { + $this->cacheEngine = $cacheEngine; + + $object = new CachePool($cacheEngine); + if ($object->isAvailable()) { + // First time + $item = $object->getItem('chave'); + $this->assertFalse($item->isHit()); + + // Set object + $model = new Model(10, 20); + $item->set($model); + $object->save($item); + $this->assertTrue($item->isHit()); + + // Get Object + $item2 = $object->getItem('chave'); + $this->assertTrue($item2->isHit()); + $this->assertEquals($model, $item2->get()); + + // Remove + $object->deleteItem('chave'); + + // Check Removed + $item = $object->getItem('chave'); + $this->assertFalse($item->isHit()); + } else { + $this->markTestIncomplete('Object is not fully functional'); + } + } } From 4daf949b58e5f1e7966739496071b904ed329dbd Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sat, 27 May 2017 15:49:06 -0300 Subject: [PATCH 14/16] Try to fix travis error. --- .travis.yml | 1 + src/Psr16/MemcachedEngine.php | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 2938ec0..f81e7a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,7 @@ addons: - redis-container php: + - "7.1" - "7.0" - "5.6" diff --git a/src/Psr16/MemcachedEngine.php b/src/Psr16/MemcachedEngine.php index 2041e42..e445992 100644 --- a/src/Psr16/MemcachedEngine.php +++ b/src/Psr16/MemcachedEngine.php @@ -119,6 +119,7 @@ public function isAvailable() public function clear() { + $this->lazyLoadMemCachedServers(); $result = $this->memCached->flush(); return $result; } From 18c5a847d137851e6615f58ad80dc659ba7c6b6b Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sat, 27 May 2017 15:55:36 -0300 Subject: [PATCH 15/16] Try to fix travis error. --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f81e7a9..f0b6a45 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,12 @@ php: - "7.0" - "5.6" +before_install: + - echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini + - echo "extension = redis.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini + install: - composer install -script: +script: - phpunit --stderr From 337c29feb9bb95a206fb939a6feca3efa4f3209e Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sat, 27 May 2017 16:07:36 -0300 Subject: [PATCH 16/16] Minor adjustments --- src/Factory.php | 2 +- src/Psr16/ArrayCacheEngine.php | 5 ++--- src/Psr16/BaseCacheEngine.php | 2 ++ src/Psr16/FileSystemCacheEngine.php | 3 ++- src/Psr16/MemcachedEngine.php | 1 - src/Psr16/NoCacheEngine.php | 2 +- src/Psr16/RedisCacheEngine.php | 2 +- src/Psr16/ShmopCacheEngine.php | 2 +- src/Psr6/CachePool.php | 2 -- 9 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Factory.php b/src/Factory.php index c62f989..0e3c463 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -9,7 +9,7 @@ use ByJG\Cache\Psr16\RedisCacheEngine; use ByJG\Cache\Psr16\SessionCacheEngine; use ByJG\Cache\Psr16\ShmopCacheEngine; -use ByJG\Cache\Psr\CachePool; +use ByJG\Cache\Psr6\CachePool; class Factory { diff --git a/src/Psr16/ArrayCacheEngine.php b/src/Psr16/ArrayCacheEngine.php index d0482ad..d6e6120 100644 --- a/src/Psr16/ArrayCacheEngine.php +++ b/src/Psr16/ArrayCacheEngine.php @@ -3,7 +3,6 @@ namespace ByJG\Cache\Psr16; use Psr\Log\NullLogger; -use Psr\SimpleCache\DateInterval; class ArrayCacheEngine extends BaseCacheEngine { @@ -67,7 +66,7 @@ public function get($key, $default = null) * * @param string $key The key of the item to store. * @param mixed $value The value of the item to store, must be serializable. - * @param null|int|DateInterval $ttl Optional. The TTL value of this item. If no value is sent and + * @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and * the driver supports TTL then the library may set a default value * for it or let the driver take care of that. * @@ -97,7 +96,7 @@ public function clear() * Unlock resource * * @param string $key - * @return bool|void + * @return bool */ public function delete($key) { diff --git a/src/Psr16/BaseCacheEngine.php b/src/Psr16/BaseCacheEngine.php index bfae281..2c49ef4 100644 --- a/src/Psr16/BaseCacheEngine.php +++ b/src/Psr16/BaseCacheEngine.php @@ -47,5 +47,7 @@ protected function addToNow($ttl) $now->add($ttl); return $now->getTimestamp(); } + + return null; } } \ No newline at end of file diff --git a/src/Psr16/FileSystemCacheEngine.php b/src/Psr16/FileSystemCacheEngine.php index 797c50d..9fd19cf 100644 --- a/src/Psr16/FileSystemCacheEngine.php +++ b/src/Psr16/FileSystemCacheEngine.php @@ -66,7 +66,7 @@ public function get($key, $default = null) * * @param string $key The key of the item to store. * @param mixed $value The value of the item to store, must be serializable. - * @param null|int|DateInterval $ttl Optional. The TTL value of this item. If no value is sent and + * @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and * the driver supports TTL then the library may set a default value * for it or let the driver take care of that. * @@ -177,6 +177,7 @@ public function clear() foreach ($list as $file) { unlink($file); } + return true; } /** diff --git a/src/Psr16/MemcachedEngine.php b/src/Psr16/MemcachedEngine.php index e445992..9349ca7 100644 --- a/src/Psr16/MemcachedEngine.php +++ b/src/Psr16/MemcachedEngine.php @@ -2,7 +2,6 @@ namespace ByJG\Cache\Psr16; -use ByJG\Cache\CacheEngineInterface; use Memcached; use Psr\Log\NullLogger; diff --git a/src/Psr16/NoCacheEngine.php b/src/Psr16/NoCacheEngine.php index cc2e279..d9d5c20 100644 --- a/src/Psr16/NoCacheEngine.php +++ b/src/Psr16/NoCacheEngine.php @@ -28,8 +28,8 @@ public function set($key, $value, $ttl = 0) } /** - * Unlock resource * @param string $key + * @return bool */ public function delete($key) { diff --git a/src/Psr16/RedisCacheEngine.php b/src/Psr16/RedisCacheEngine.php index 7b0f274..4aa3e14 100644 --- a/src/Psr16/RedisCacheEngine.php +++ b/src/Psr16/RedisCacheEngine.php @@ -57,7 +57,7 @@ protected function fixKey($key) { /** * @param string $key The object KEY * @param int $default IGNORED IN MEMCACHED. - * @return object Description + * @return mixed Description */ public function get($key, $default = null) { diff --git a/src/Psr16/ShmopCacheEngine.php b/src/Psr16/ShmopCacheEngine.php index 2b3afbf..551a94e 100644 --- a/src/Psr16/ShmopCacheEngine.php +++ b/src/Psr16/ShmopCacheEngine.php @@ -120,7 +120,7 @@ protected function isValidAge($file) * * @param string $key The key of the item to store. * @param mixed $value The value of the item to store, must be serializable. - * @param null|int|DateInterval $ttl Optional. The TTL value of this item. If no value is sent and + * @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and * the driver supports TTL then the library may set a default value * for it or let the driver take care of that. * @return bool True on success and false on failure. diff --git a/src/Psr6/CachePool.php b/src/Psr6/CachePool.php index 9c4db04..9dcf165 100644 --- a/src/Psr6/CachePool.php +++ b/src/Psr6/CachePool.php @@ -2,12 +2,10 @@ namespace ByJG\Cache\Psr6; -use ByJG\Cache\CacheEngineInterface; use ByJG\Cache\Psr16\BaseCacheEngine; use Psr\Cache\CacheItemInterface; use Psr\Cache\CacheItemPoolInterface; use Psr\Log\InvalidArgumentException; -use Psr\SimpleCache\CacheInterface; class CachePool implements CacheItemPoolInterface {