Merge pull request #143 from Skyscanner/ttl-feature

Implementation of TTL for caching
This commit is contained in:
Behrooz Shabani 2016-07-26 10:51:07 +02:00 committed by GitHub
commit a00af06cac
7 changed files with 187 additions and 19 deletions

View File

@ -9,6 +9,7 @@
* @package Handlebars
* @author fzerorubigd <fzerorubigd@gmail.com>
* @author Behrooz Shabani <everplays@gmail.com>
* @author Mária Šormanová <maria.sormanova@gmail.com>
* @copyright 2012 (c) ParsPooyesh Co
* @copyright 2013 (c) Behrooz Shabani
* @license MIT <http://opensource.org/licenses/MIT>
@ -46,14 +47,17 @@ interface Cache
public function get($name);
/**
* Set a cache
* Set a cache with $ttl, if present
* If $ttl set to -1, the cache expires immediately
* If $ttl set to 0 (default), cache is never purged
*
* @param string $name cache id
* @param mixed $value data to store
* @param int $ttl time to live in seconds
*
* @return void
*/
public function set($name, $value);
public function set($name, $value, $ttl = 0);
/**
* Remove cache

View File

@ -9,6 +9,7 @@
* @package Handlebars
* @author Joey Baker <joey@byjoeybaker.com>
* @author Behrooz Shabani <everplays@gmail.com>
* @author Mária Šormanová <maria.sormanova@gmail.com>
* @copyright 2013 (c) Meraki, LLP
* @copyright 2013 (c) Behrooz Shabani
* @license MIT <http://opensource.org/licenses/MIT>
@ -50,11 +51,12 @@ class APC implements Cache
}
/**
* Get cache for $name if exist.
* Get cache for $name if exist
* and if the cache is not older than defined TTL.
*
* @param string $name Cache id
*
* @return mixed data on hit, boolean false on cache not found
* @return mixed data on hit, boolean false on cache not found/expired
*/
public function get($name)
{
@ -66,16 +68,19 @@ class APC implements Cache
}
/**
* Set a cache
* Set a cache with $ttl, if present
* If $ttl set to -1, the cache expires immediately
* If $ttl set to 0 (default), cache is never purged
*
* @param string $name cache id
* @param mixed $value data to store
* @param int $ttl time to live in seconds
*
* @return void
*/
public function set($name, $value)
public function set($name, $value, $ttl = 0)
{
apc_store($this->_getKey($name), $value);
apc_store($this->_getKey($name), $value, $ttl);
}
/**

View File

@ -9,6 +9,7 @@
* @package Handlebars
* @author Alex Soncodi <alex@brokerloop.com>
* @author Behrooz Shabani <everplays@gmail.com>
* @author Mária Šormanová <maria.sormanova@gmail.com>
* @copyright 2013 (c) Brokerloop, Inc.
* @copyright 2013 (c) Behrooz Shabani
* @license MIT <http://opensource.org/licenses/MIT>
@ -25,6 +26,7 @@ use Handlebars\Cache;
* @category Xamin
* @package Handlebars
* @author Alex Soncodi <alex@brokerloop.com>
* @author Mária Šormanová <maria.sormanova@gmail.com>
* @copyright 2013 (c) Brokerloop, Inc.
* @license MIT <http://opensource.org/licenses/MIT>
* @version Release: @package_version@
@ -81,33 +83,49 @@ class Disk implements Cache
}
/**
* Get cache for $name if it exists.
* Get cache for $name if it exists
* and if the cache is not older than defined TTL.
*
* @param string $name Cache id
*
* @return mixed data on hit, boolean false on cache not found
* @return mixed data on hit, boolean false on cache not found/expired
*/
public function get($name)
{
$path = $this->_getPath($name);
return (file_exists($path)) ?
unserialize(file_get_contents($path)) : false;
$output = false;
if (file_exists($path)) {
$file = fopen($path, "r");
$ttl = fgets($file);
$ctime = filectime($path);
$time = time();
if ($ttl == -1 || ($ttl > 0 && $time - $ctime > $ttl)) {
unlink($path);
} else {
$serialized_data = fread($file, filesize($path));
$output = unserialize($serialized_data);
}
fclose($file);
}
return $output;
}
/**
* Set a cache
* Set a cache with $ttl, if present
* If $ttl set to -1, the cache expires immediately
* If $ttl set to 0 (default), cache is never purged
*
* @param string $name cache id
* @param mixed $value data to store
* @param int $ttl time to live in seconds
*
* @return void
*/
public function set($name, $value)
public function set($name, $value, $ttl = 0)
{
$path = $this->_getPath($name);
file_put_contents($path, serialize($value));
file_put_contents($path, $ttl.PHP_EOL.serialize($value));
}
/**

View File

@ -9,6 +9,7 @@
* @package Handlebars
* @author fzerorubigd <fzerorubigd@gmail.com>
* @author Behrooz Shabani <everplays@gmail.com>
* @author Mária Šormanová <maria.sormanova@gmail.com>
* @copyright 2012 (c) ParsPooyesh Co
* @copyright 2013 (c) Behrooz Shabani
* @license MIT <http://opensource.org/licenses/MIT>
@ -55,10 +56,14 @@ class Dummy implements Cache
*
* @param string $name cache id
* @param mixed $value data to store
* @param int $ttl time to live in seconds
*
* $ttl is ignored since the cache is implemented
* by an array and lives only inside one request
*
* @return void
*/
public function set($name, $value)
public function set($name, $value, $ttl = 0)
{
$this->_cache[$name] = $value;
}

View File

@ -10,6 +10,7 @@
* @author fzerorubigd <fzerorubigd@gmail.com>
* @author Behrooz Shabani <everplays@gmail.com>
* @author Jeff Turcotte <jeff.turcotte@gmail.com>
* @author Mária Šormanová <maria.sormanova@gmail.com>
* @copyright 2010-2012 (c) Justin Hileman
* @copyright 2012 (c) ParsPooyesh Co
* @copyright 2013 (c) Behrooz Shabani
@ -37,7 +38,7 @@ use Handlebars\Cache\Dummy;
class Handlebars
{
private static $_instance = false;
const VERSION = '1.0.0';
const VERSION = '1.1.0';
/**
* factory method
@ -85,6 +86,13 @@ class Handlebars
*/
private $_cache;
/**
* @var int time to live parameter in seconds for the cache usage
* default set to 0 which means that entries stay in cache
* forever and are never purged
*/
private $_ttl = 0;
/**
* @var string the class to use for the template
*/
@ -138,6 +146,10 @@ class Handlebars
$this->setCache($options['cache']);
}
if (isset($options['ttl'])) {
$this->setTtl($options['ttl']);
}
if (isset($options['template_class'])) {
$this->setTemplateClass($options['template_class']);
}
@ -337,6 +349,28 @@ class Handlebars
return $this->_cache;
}
/**
* Set time to live for the used cache
*
* @param int $ttl time to live in seconds
*
* @return void
*/
public function setTtl($ttl)
{
$this->_ttl = $ttl;
}
/**
* Get ttl
*
* @return int
*/
public function getTtl()
{
return $this->_ttl;
}
/**
* Get current escape function
*
@ -545,7 +579,7 @@ class Handlebars
}
/**
* try to tokenize source, or get them from cache if available
* Try to tokenize source, or get them from cache if available
*
* @param string $source handlebars source code
*
@ -558,7 +592,7 @@ class Handlebars
if ($tree === false) {
$tokens = $this->getTokenizer()->scan($source);
$tree = $this->getParser()->parse($tokens);
$this->getCache()->set($hash, $tree);
$this->getCache()->set($hash, $tree, $this->_ttl);
}
return $tree;

View File

@ -9,6 +9,7 @@
* @package Handlebars
* @author fzerorubigd <fzerorubigd@gmail.com>
* @author Dmitriy Simushev <simushevds@gmail.com>
* @author Mária Šormanová <maria.sormanova@gmail.com>
* @copyright 2013 (c) f0ruD A
* @license MIT <http://opensource.org/licenses/MIT>
* @version GIT: $Id$
@ -92,9 +93,26 @@ class APCTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(20, $driver->get('foo'));
$driver->set('foo', array(22));
$this->assertEquals(array(22), $driver->get('foo'));
$driver->remove('foo');
$this->assertEquals(false, $driver->get('foo'));
}
/**
* Test ttl
*
* @return void
*/
public function testTtl()
{
$driver = $this->_getCacheDriver();
$driver->set('foo', 10, -1);
$this->assertEquals(false, $driver->get('foo'));
$driver->set('foo', 20, 3600);
$this->assertEquals(20, $driver->get('foo'));
}
}

View File

@ -0,0 +1,84 @@
<?php
/**
* This file is part of Handlebars-php
* Base on mustache-php https://github.com/bobthecow/mustache.php
*
* PHP version 5.3
*
* @category Xamin
* @package Handlebars
* @author Mária Šormanová <maria.sormanova@gmail.com>
* @copyright 2016 (c) Mária Šormanová
* @license MIT <http://opensource.org/licenses/MIT>
* @version GIT: $Id$
* @link http://xamin.ir
*/
/**
* Test of Disk cache driver
*
* @category Xamin
* @package Handlebars
* @subpackage Test
* @author Mária Šormanová <maria.sormanova@gmail.com>
* @license MIT <http://opensource.org/licenses/MIT>
* @version Release: @package_version@
* @link http://xamin.ir
*/
class DiskTest extends \PHPUnit_Framework_TestCase
{
/**
* {@inheritdoc}
*
* @return void
*/
public function setUp()
{
\Handlebars\Autoloader::register();
}
/**
* Return the new driver
*
* @param string $path folder where the cache is located
*
* @return \Handlebars\Cache\Disk
*/
private function _getCacheDriver( $path = '')
{
return new \Handlebars\Cache\Disk($path);
}
/**
* Test the Disk cache
*
* @return void
*/
public function testDiskCache()
{
$cache_dir = getcwd().'/tests/cache';
$driver = $this->_getCacheDriver($cache_dir);
$this->assertEquals(false, $driver->get('foo'));
$driver->set('foo', "hello world");
$this->assertEquals("hello world", $driver->get('foo'));
$driver->set('foo', "hello world", -1);
$this->assertEquals(false, $driver->get('foo'));
$driver->set('foo', "hello world", 3600);
$this->assertEquals("hello world", $driver->get('foo'));
$driver->set('foo', array(12));
$this->assertEquals(array(12), $driver->get('foo'));
$driver->remove('foo');
$this->assertEquals(false, $driver->get('foo'));
rmdir($cache_dir);
}
}
?>