Completely rewrite cache layer to use new "cache.conf.php" for both dev and production, allowing easy testing of cache platforms. Add support for Redis throughout the stack as well.

This commit is contained in:
Buster "Silver Eagle" Neece 2015-05-27 20:18:05 -05:00
parent 2df27cd05d
commit 524eceb363
8 changed files with 179 additions and 109 deletions

1
.gitignore vendored
View File

@ -8,6 +8,7 @@ app/config/db.conf.php
app/config/apis.conf.php
app/config/influx.conf.php
app/config/memcached.conf.php
app/config/cache.conf.php
# Junk/cache files.
*Thumbs.db

View File

@ -0,0 +1,42 @@
<?php
/**
* Backend cache configuration.
*/
return array(
// Valid options are:
// ephemeral - Uses in-memory cache that expires at page request.
// memcached - Uses libmemcached and 'memcached' settings below.
// redis - Uses phpredis and 'redis' settings below.
// file - Uses flat-file storage and 'file' settings below.
'cache' => 'ephemeral',
// Flatfile configuration
'file' => array(
'cacheDir' => DF_INCLUDE_CACHE.DIRECTORY_SEPARATOR,
),
// Redis configuration
'redis' => array(
'host' => 'localhost',
'port' => 6379, // default: 6379
'auth' => '',
'persistent' => false
),
// Memcached configuration
'memcached' => array(
'servers' => array(
'main' => array(
// Host or IP to connect to (default: localhost, port 11211).
'host' => 'localhost',
'port' => 11211,
// Priority for cache storage.
'weight' => 1,
),
),
'client' => array(),
),
);

View File

@ -1,18 +0,0 @@
<?php
/**
* Memcached configuration and credentials.
*/
return array(
'servers' => array(
'main' => array(
// Host or IP to connect to (default: localhost).
'host' => 'localhost',
'port' => 11211,
// Priority for cache storage.
'weight' => 1,
),
),
);

View File

@ -96,26 +96,42 @@ class Cache
$cache = self::getCache();
return $cache->queryKeys(self::getSitePrefix('user'));
}
// Retrieve or initialize the cache.
protected static $_user_cache;
public static function getCache()
/**
* @param string $cache_level
* @return \Phalcon\Cache\BackendInterface
*/
public static function getCache($cache_level = 'user')
{
return self::getUserCache();
}
public static function getUserCache()
{
if (!is_object(self::$_user_cache))
if ($cache_level == 'user')
{
return self::getUserCache();
}
else
{
$frontend = new \Phalcon\Cache\Frontend\Data();
self::$_user_cache = self::getBackendCache($frontend);
return self::getBackendCache($frontend, $cache_level);
}
return self::$_user_cache;
}
/**
* Get the static user cache.
*
* @return \Phalcon\Cache\BackendInterface
*/
public static function getUserCache()
{
static $user_cache;
if (!$user_cache)
{
$frontend = new \Phalcon\Cache\Frontend\Data();
$user_cache = self::getBackendCache($frontend, 'user');
}
return $user_cache;
}
/**
* Page Cache
public static function page()
@ -157,46 +173,70 @@ class Cache
return self::$_page_cache;
}
*/
/**
* Generic Cache Details
* @param \Phalcon\Cache\FrontendInterface $frontCache
* @param string $cache_level
* @return \Phalcon\Cache\BackendInterface
*/
public static function getSitePrefix($cache_level = 'user')
public static function getBackendCache(\Phalcon\Cache\FrontendInterface $frontCache, $cache_level = 'user')
{
$folders = explode(DIRECTORY_SEPARATOR, DF_INCLUDE_ROOT);
$base_folder = @array_pop($folders);
if (strpos($base_folder, '.') !== FALSE)
$base_folder = substr($base_folder, 0, strpos($base_folder, '.'));
$di = \Phalcon\Di::getDefault();
$config = $di->get('config');
$cache_base = ($base_folder) ? preg_replace("/[^a-zA-Z0-9]/", "", $base_folder) : 'default';
return $cache_base.'.'.$cache_level.'.';
}
public static function getBackendCache(\Phalcon\Cache\FrontendInterface $frontCache)
{
$cache_dir = DF_INCLUDE_CACHE;
$cache_prefix = self::getSitePrefix('user');
$cache_config = $config->cache->toArray();
if (DF_APPLICATION_ENV == 'production') {
$di = \Phalcon\Di::getDefault();
$config = $di->get('config');
switch($cache_config['cache'])
{
case 'redis':
$redis_config = (array)$cache_config['redis'];
$redis_config['prefix'] = self::getSitePrefix($cache_level, ':');
$servers = array_values($config->memcached->servers->toArray());
return new \Phalcon\Cache\Backend\Redis($frontCache, $redis_config);
break;
return new \Phalcon\Cache\Backend\Libmemcached($frontCache, array(
'servers' => $servers,
'client' => array(
\Memcached::OPT_HASH => \Memcached::HASH_MD5,
\Memcached::OPT_PREFIX_KEY => $cache_prefix,
),
));
} else {
return new \Phalcon\Cache\Backend\File($frontCache, array(
'cacheDir' => $cache_dir.DIRECTORY_SEPARATOR,
'prefix' => $cache_prefix,
));
case 'memcached':
$memcached_config = (array)$cache_config['memcached'];
$memcached_config['client'][\Memcached::OPT_PREFIX_KEY] = self::getSitePrefix($cache_level, '.');
return new \Phalcon\Cache\Backend\Libmemcached($frontCache, $memcached_config);
break;
case 'file':
$file_config = (array)$cache_config['file'];
$file_config['prefix'] = self::getSitePrefix($cache_level, '_');
return new \Phalcon\Cache\Backend\File($frontCache, $file_config);
break;
default:
case 'memory':
case 'ephemeral':
return new \Phalcon\Cache\Backend\Memory($frontCache);
break;
}
}
/**
* @param string $cache_level
* @param string $cache_separator
* @return string Compiled site prefix for cache use.
*/
public static function getSitePrefix($cache_level = 'user', $cache_separator = '.')
{
static $cache_base;
if (!$cache_base)
{
$folders = explode(DIRECTORY_SEPARATOR, DF_INCLUDE_ROOT);
$base_folder = @array_pop($folders);
if (strpos($base_folder, '.') !== FALSE)
$base_folder = substr($base_folder, 0, strpos($base_folder, '.'));
$cache_base = ($base_folder) ? preg_replace("/[^a-zA-Z0-9]/", "", $base_folder) : 'default';
}
return $cache_base.$cache_separator.$cache_level.$cache_separator;
}
}

View File

@ -7,12 +7,22 @@ namespace DF\Doctrine;
class Cache extends \Doctrine\Common\Cache\CacheProvider
{
/**
* @var \Phalcon\Cache\BackendInterface
*/
protected $_cache;
public function __construct()
{
$this->_cache = \DF\Cache::getCache('doctrine');
}
protected function doFetch($id, $testCacheValidity = true)
{
$id = $this->_filterCacheId($id);
if (!$testCacheValidity || \DF\Cache::test($id))
return \DF\Cache::get($id);
if (!$testCacheValidity || $this->_cache->exists($id))
return $this->_cache->get($id);
else
return FALSE;
}
@ -20,21 +30,23 @@ class Cache extends \Doctrine\Common\Cache\CacheProvider
protected function doContains($id)
{
$id = $this->_filterCacheId($id);
return \DF\Cache::test($id);
return $this->_cache->exists($id);
}
protected function doSave($id, $data, $lifeTime = NULL)
{
if ($lifeTime == 0)
$lifeTime = NULL;
\DF\Cache::save($data, $this->_filterCacheId($id), array(), $lifeTime);
if ($lifeTime == 0 || $lifeTime == NULL)
$lifeTime = 3600;
$id = $this->_filterCacheId($id);
$this->_cache->save($id, $data, $lifeTime);
return true;
}
protected function doDelete($id)
{
\DF\Cache::remove($this->_filterCacheId($id));
$id = $this->_filterCacheId($id);
$this->_cache->delete($id);
}
protected function doGetStats()
@ -44,13 +56,13 @@ class Cache extends \Doctrine\Common\Cache\CacheProvider
protected function doFlush()
{
\DF\Cache::clean('all');
$this->_cache->flush();
}
public function getIds()
{
$all_keys = \DF\Cache::getKeys();
$all_keys = $this->_cache->queryKeys();
if (!$this->getNamespace())
{
return $all_keys;

View File

@ -49,16 +49,8 @@ class Doctrine
$metadata_driver = $config->newDefaultAnnotationDriver($options['modelPath']);
$config->setMetadataDriverImpl($metadata_driver);
$regen_proxies = FALSE;
if (DF_APPLICATION_ENV == "production" && !DF_IS_COMMAND_LINE)
{
$cache = new \DF\Doctrine\Cache;
$cache->setNamespace('doctrine_');
}
else
{
$cache = new \Doctrine\Common\Cache\ArrayCache;
}
$cache = new \DF\Doctrine\Cache;
// $cache->setNamespace('doctrine_');
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);
@ -81,13 +73,6 @@ class Doctrine
$em->getFilters()->enable("softdelete");
// Trigger proxy regeneration.
if ($regen_proxies)
{
$metadatas = $em->getMetadataFactory()->getAllMetadata();
$em->getProxyFactory()->generateProxyClasses($metadatas);
}
// Try the connection before rendering the page.
$em->getConnection()->connect();

View File

@ -23,7 +23,7 @@ class Settings extends \DF\Doctrine\Entity
* Static Functions
*/
public static function setSetting($key, $value)
public static function setSetting($key, $value, $flush_cache = false)
{
$record = self::getRepository()->findOneBy(array('setting_key' => $key));
@ -36,7 +36,8 @@ class Settings extends \DF\Doctrine\Entity
$record->setting_value = $value;
$record->save();
self::clearCache();
if ($flush_cache)
self::clearCache();
}
public static function getSetting($key, $default_value = NULL, $cached = TRUE)
@ -63,21 +64,26 @@ class Settings extends \DF\Doctrine\Entity
public static function fetchArray($cached = true)
{
$settings = \DF\Cache::get('all_settings');
static $settings;
if (!$settings || !$cached)
{
$em = self::getEntityManager();
$settings_raw = $em->createQuery('SELECT s FROM '.__CLASS__.' s ORDER BY s.setting_key ASC')
->getArrayResult();
$settings = array();
foreach((array)$settings_raw as $setting)
{
$settings[$setting['setting_key']] = $setting['setting_value'];
}
$settings = \DF\Cache::get('all_settings');
\DF\Cache::save($settings, 'all_settings', array(), 86400);
if (!$settings || !$cached)
{
$em = self::getEntityManager();
$settings_raw = $em->createQuery('SELECT s FROM '.__CLASS__.' s ORDER BY s.setting_key ASC')
->getArrayResult();
$settings = array();
foreach((array)$settings_raw as $setting)
{
$settings[$setting['setting_key']] = $setting['setting_value'];
}
\DF\Cache::save($settings, 'all_settings', array(), 8640);
}
}
return $settings;

View File

@ -24,8 +24,10 @@ class SettingsController extends BaseController
foreach($data as $key => $value)
{
Settings::setSetting($key, $value);
}
}
Settings::clearCache();
$this->alert('Settings updated!');
return $this->redirectHere();
}