Start of caching implementation

This commit is contained in:
Timothy Warren 2016-04-05 13:19:35 -04:00
parent 972d96c0e0
commit 84e4e6ce1b
8 changed files with 277 additions and 43 deletions

View File

@ -15,6 +15,7 @@ use Zend\Diactoros\ServerRequestFactory;
use Zend\Diactoros\Response; use Zend\Diactoros\Response;
use Aviat\Ion\Di\Container; use Aviat\Ion\Di\Container;
use Aviat\Ion\Cache\CacheManager;
use Aviat\AnimeClient\Auth\HummingbirdAuth; use Aviat\AnimeClient\Auth\HummingbirdAuth;
use Aviat\AnimeClient\Model; use Aviat\AnimeClient\Model;
@ -30,7 +31,6 @@ return function(array $config_array = []) {
$app_logger = new Logger('animeclient'); $app_logger = new Logger('animeclient');
$app_logger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/app.log', Logger::NOTICE)); $app_logger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/app.log', Logger::NOTICE));
$app_logger->pushHandler(new BrowserConsoleHandler(Logger::INFO));
$container->setLogger($app_logger, 'default'); $container->setLogger($app_logger, 'default');
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -83,6 +83,8 @@ return function(array $config_array = []) {
$container->set('anime-collection-model', new Model\AnimeCollection($container)); $container->set('anime-collection-model', new Model\AnimeCollection($container));
$container->set('auth', new HummingbirdAuth($container)); $container->set('auth', new HummingbirdAuth($container));
$container->set('cache', new CacheManager($container));
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Dispatcher // Dispatcher

View File

@ -14,5 +14,8 @@ show_anime_collection = true
# do you wish to show the manga collection? # do you wish to show the manga collection?
show_manga_collection = false show_manga_collection = false
# cache driver for api calls (SQLDriver, RedisDriver, MemcacheDriver)
cache_driver = SQLDriver
# path to public directory on the server # path to public directory on the server
asset_dir = "/../../public" asset_dir = "/../../public"

View File

@ -27,8 +27,8 @@ class CacheMigration extends AbstractMigration
*/ */
public function change() public function change()
{ {
$this->table('cache', ['id' => FALSE, 'primary_key' => ['key']]) $cacheTable = $this->table('cache', ['id' => FALSE, 'primary_key' => ['key']]);
->addColumn('key', 'text') $cacheTable->addColumn('key', 'text')
->addColumn('value', 'text') ->addColumn('value', 'text')
->create(); ->create();
} }

View File

@ -37,6 +37,11 @@ class Anime extends BaseController {
* @var array $base_data * @var array $base_data
*/ */
protected $base_data; protected $base_data;
/**
* Data cache
*/
protected $cache;
/** /**
* Constructor * Constructor
@ -55,6 +60,8 @@ class Anime extends BaseController {
'other_type' => 'manga', 'other_type' => 'manga',
'config' => $this->config, 'config' => $this->config,
]); ]);
$this->cache = $container->get('cache');
} }
/** /**
@ -98,10 +105,14 @@ class Anime extends BaseController {
'' => 'cover', '' => 'cover',
'list' => 'list' 'list' => 'list'
]; ];
$data = ($type != 'all') $data = ($type != 'all')
? $this->cache->get($this->model, 'get_list', ['status' => $model_map[$type]])
: $this->cache->get($this->model, 'get_all_lists', []);
/*$data = ($type != 'all')
? $this->model->get_list($model_map[$type]) ? $this->model->get_list($model_map[$type])
: $this->model->get_all_lists(); : $this->model->get_all_lists();*/
$this->outputHTML('anime/' . $view_map[$view], [ $this->outputHTML('anime/' . $view_map[$view], [
'title' => $title, 'title' => $title,

View File

@ -1,36 +1,44 @@
<?php <?php
/** /**
* Ion * Ion
* *
* Building blocks for web development * Building blocks for web development
* *
* @package Ion * @package Ion
* @author Timothy J. Warren * @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016 * @copyright Copyright (c) 2015 - 2016
* @license MIT * @license MIT
*/ */
namespace Aviat\Ion\Cache; namespace Aviat\Ion\Cache;
/** /**
* Interface for cache drivers * Interface for cache drivers
*/ */
interface CacheDriverInterface { interface CacheDriverInterface {
/** /**
* Retreive a value from the cache backend * Retreive a value from the cache backend
* *
* @param string $key * @param string $key
* @return mixed * @return mixed
*/ */
public function get($key); public function get($key);
/** /**
* Set a cached value * Set a cached value
* *
* @param string $key * @param string $key
* @param mixed $value * @param mixed $value
* @return CacheDriverInterface * @return CacheDriverInterface
*/ */
public function set($key, $value); public function set($key, $value);
}
/**
* Invalidate a cached value
*
* @param string $key
* @return CacheDriverInterface
*/
public function invalidate($key);
}
// End of CacheDriverInterface.php // End of CacheDriverInterface.php

View File

@ -23,9 +23,9 @@ interface CacheInterface {
* *
* @param object $object - object to retrieve fresh value from * @param object $object - object to retrieve fresh value from
* @param string $method - method name to call * @param string $method - method name to call
* @param array $args - the arguments to pass to the retrieval method * @param [array] $args - the arguments to pass to the retrieval method
* @return mixed - the cached or fresh data * @return mixed - the cached or fresh data
*/ */
public function get($object, $method, array $args); public function get($object, $method, array $args=[]);
} }
// End of CacheInterface.php // End of CacheInterface.php

View File

@ -0,0 +1,100 @@
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
namespace Aviat\Ion\Cache;
use \Aviat\Ion\Di\ContainerInterface;
/**
* Class proxying cached and fresh values from the selected cache driver
*/
class CacheManager implements CacheInterface {
/**
* @var CacheDriverInterface
*/
protected $driver;
/**
* Retreive the appropriate driver from the container
*/
public function __construct(ContainerInterface $container)
{
$config = $container->get('config');
$driverConf = $config->get('cache_driver');
$driverClass = __NAMESPACE__ . "\\Driver\\{$driverConf}";
$driver = new $driverClass($container);
$this->driver = $driver;
}
/**
* Retreive a cached value if it exists, otherwise, get the value
* from the passed arguments
*
* @param object $object - object to retrieve fresh value from
* @param string $method - method name to call
* @param [array] $args - the arguments to pass to the retrieval method
* @return mixed - the cached or fresh data
*/
public function get($object, $method, array $args=[])
{
$hash = $this->generateHashForMethod($object, $method, $args);
$data = $this->driver->get($hash);
if (empty($data))
{
$data = call_user_func_array([$object, $method], $args);
$this->driver->set($hash, $data);
}
return $data;
}
/**
* Retreive a fresh value from the method, and update the cache
* @param object $object - object to retrieve fresh value from
* @param string $method - method name to call
* @param [array] $args - the arguments to pass to the retrieval method
* @return mixed - the fresh data
*/
public function getFresh($object, $method, array $args=[])
{
$hash = $this->generateHashForMethod($object, $method, $args);
$data = call_user_func_array([$object, $method], $args);
$this->driver->set($hash, $data);
return $data;
}
/**
* Generate a hash as a cache key from the current method call
*
* @param object $object
* @param string $method
* @param array $args
* @return string
*/
public function generateHashForMethod($object, $method, array $args)
{
$classname = get_class($object);
$keyObj = [
'class' => $classname,
'method' => $method,
'args' => $args,
];
$hash = sha1(json_encode($keyObj));
return $hash;
}
}
// End of CacheManager.php

View File

@ -0,0 +1,110 @@
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
namespace Aviat\Ion\Cache\Driver;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Json;
use Aviat\AnimeClient\Model\DB;
/**
* Driver for caching via a traditional SQL database
*/
class SQLDriver extends DB implements \Aviat\Ion\Cache\CacheDriverInterface {
/**
* The query builder object
* @var object $db
*/
protected $db;
/**
* Create the driver object
*/
public function __construct(ContainerInterface $container)
{
parent::__construct($container);
try
{
$this->db = \Query($this->db_config['collection']);
}
catch (\PDOException $e)
{
$this->valid_database = FALSE;
return FALSE;
}
}
/**
* Retreive a value from the cache backend
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$query = $this->db->select('value')
->from('cache')
->where('key', $key)
->get();
$row = $query->fetch(\PDO::FETCH_ASSOC);
if ( ! empty($row))
{
return unserialize($row['value']);
}
return NULL;
}
/**
* Set a cached value
*
* @param string $key
* @param mixed $value
* @return CacheDriverInterface
*/
public function set($key, $value)
{
$this->db->set([
'key' => $key,
'value' => serialize($value),
]);
/*if ( ! empty($this->get($key)))
{
$this->db->update('cache');
}
else*/
{
$this->db->insert('cache');
}
return $this;
}
/**
* Invalidate a cached value
*
* @param string $key
* @return CacheDriverInterface
*/
public function invalidate($key)
{
$this->db->where('key', $key)
->delete('cache');
return $this;
}
}
// End of SQLDriver.php