Attached Files |
apc_caching_support.patch [^] (19,766 bytes) 2010-03-02 11:45
[Show Content]
Index: install/install_data.sql
===================================================================
--- install/install_data.sql (revision 13168)
+++ install/install_data.sql (working copy)
@@ -177,6 +177,8 @@
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CSVExportEncoding', '0', 'In-Portal', 'in-portal:configure_advanced');
INSERT INTO ConfigurationAdmin VALUES ('MemcacheServers', 'la_section_SettingsCaching', 'la_config_MemcacheServers', 'text', '', '', 80.01, 0, 0);
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'MemcacheServers', 'localhost:11211', 'In-Portal', 'in-portal:configure_advanced');
+INSERT INTO ConfigurationAdmin VALUES ('CacheHandler', 'la_section_SettingsCaching', 'la_config_CacheHandler', 'select', NULL, 'Fake=la_None,Memcache=+Memcached,Apc=+Alternative PHP Cache', 80.02, 0, 0);
+INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CacheHandler', 'Fake', 'In-Portal', 'in-portal:configure_advanced');
# Section "in-portal:configure_users":
INSERT INTO ConfigurationAdmin VALUES ('User_Allow_New', 'la_title_General', 'la_users_allow_new', 'radio', '', '1=la_opt_UserInstantRegistration,2=la_opt_UserNotAllowedRegistration,3=la_opt_UserUponApprovalRegistration,4=la_opt_UserEmailActivation', 10.01, 0, 1);
Index: install/upgrades.sql
===================================================================
--- install/upgrades.sql (revision 13168)
+++ install/upgrades.sql (working copy)
@@ -1681,4 +1681,7 @@
KEY Prefixes (Prefixes),
KEY Cached (Cached),
KEY LifeTime (LifeTime)
-);
\ No newline at end of file
+);
+
+INSERT INTO ConfigurationAdmin VALUES ('CacheHandler', 'la_section_SettingsCaching', 'la_config_CacheHandler', 'select', NULL, 'Fake=la_None,Memcache=+Memcached,Apc=+Alternative PHP Cache', 80.02, 0, 0);
+INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CacheHandler', 'Fake', 'In-Portal', 'in-portal:configure_advanced');
\ No newline at end of file
Index: kernel/utility/cache.php
===================================================================
--- kernel/utility/cache.php (revision 13168)
+++ kernel/utility/cache.php (working copy)
@@ -14,16 +14,34 @@
defined('FULL_PATH') or die('restricted access!');
+ /**
+ * Manager of all implemented caching handlers
+ *
+ */
class kCache extends kBase {
/**
- * Object, that represents cache storage
+ * Object of cache handler
*
- * @var CacheStorage
+ * @var FakeCacheHandler
*/
- var $_storage = null;
+ var $_handler = null;
/**
+ * Part of what we retrieve will be stored locally (per script run) not to bother memcache a lot
+ *
+ * @var Array
+ */
+ var $_localStorage = Array ();
+
+ /**
+ * What type of caching is being used
+ *
+ * @var int
+ */
+ var $cachingType = CACHING_TYPE_NONE;
+
+ /**
* Cache usage statistics (per script run)
*
* @var Array
@@ -37,81 +55,207 @@
*/
var $debugCache = false;
+ /**
+ * Displays cache usage statistics
+ *
+ * @var bool
+ */
+ var $displayCacheStatistics = false;
+
function kCache()
{
parent::kBase();
- $this->debugCache = defined('DBG_CACHE') && DBG_CACHE && $this->Application->isDebugMode();
-
- if (class_exists('Memcache')) {
- $this->_storage = new MemcacheCacheStorage();
+ // get cache handler class to use
+ if (array_key_exists('CacheHandler', $GLOBALS['vars']) && $GLOBALS['vars']['CacheHandler']) {
+ // for advanced users, who want to save one SQL on each page load
+ $handler_class = $GLOBALS['vars']['CacheHandler'] . 'CacheHandler';
}
else {
- $this->_storage = new CacheStorage();
+ $handler_class = $this->Application->ConfigValue('CacheHandler') . 'CacheHandler';
}
- if (!$this->_storage->isWorking()) {
- // when one of above cache storages fails to initialize fallback to memory cache
- $this->_storage = new CacheStorage();
+ // defined cache handler doen't exist -> use default
+ if (!class_exists($handler_class)) {
+ $handler_class = 'FakeCacheHandler';
}
+
+ $handler = new $handler_class();
+
+ if (!$handler->isWorking()) {
+ // defined cache handler is not working -> use default
+ trigger_error('Failed to initialize "<strong>' . $handler_class . '</strong>" caching handler.', E_USER_WARNING);
+
+ $handler = new FakeCacheHandler();
+ }
+ elseif ($this->Application->isDebugMode() && ($handler->cachingType == CACHING_TYPE_MEMORY)) {
+ $this->Application->Debugger->appendHTML('Memory Caching: "<strong>' . $handler_class . '</strong>"');
+ }
+
+ $this->_handler =& $handler;
+ $this->cachingType = $handler->cachingType;
+ $this->debugCache = $handler->cachingType == CACHING_TYPE_MEMORY && $this->Application->isDebugMode();
+ $this->displayCacheStatistics = defined('DBG_CACHE') && DBG_CACHE && $this->Application->isDebugMode();
}
/**
- * Adds new value to cache $cache_name and identified by key $name
+ * Returns caching type of current storage engine
*
- * @param int $name key name to add to cache
- * @param mixed $value value of chached record
- * @param int $expires expiration
+ * @return int
*/
- function setCache($name, $value, $expires = 0)
+ function getCachingType()
{
- return $this->_storage->set($name, $value, $expires);
+ return $this->cachingType;
}
- function reset()
+
+ /**
+ * Stores value to cache
+ *
+ * @param string $name
+ * @param mixed $value
+ * @param int $expires cache record expiration time in seconds
+ */
+ function setCache($name, $value, $expiration)
{
- return $this->_storage->reset();
+ $name = $this->prepareKeyName($name);
+ $this->_localStorage[$name] = $value;
+
+ return $this->_handler->set($name, $value, $expiration);
}
/**
- * Returns cached $name value from cache named $cache_name
+ * Returns value from cache
*
- * @param int $name key name from cache
+ * @param string $name
* @param bool $store_locally store data locally after retrieved
+ * @param bool $replace_serials
* @return mixed
*/
- function getCache($name, $store_locally = true)
+ function getCache($name, $store_locally = true, $replace_serials = true)
{
- $ret = $this->_storage->get($name, $store_locally);
+ $name = $this->prepareKeyName($name, $replace_serials);
- if ($this->debugCache && $store_locally) {
- $this->setStatistics($name, $ret);
+ if ($store_locally) {
+ if (array_key_exists($name, $this->_localStorage)) {
+ if ($this->displayCacheStatistics) {
+ $this->setStatistics($name, $this->_localStorage[$name]);
+ }
+
+ return $this->_localStorage[$name];
+ }
}
- return $ret;
+ $res = $this->_handler->get($name);
+
+ if ($replace_serials && $this->debugCache) {
+ // don't display subsequent serial cache retrievals (ones, that are part of keys)
+ if (is_array($res)) {
+ $this->Application->Debugger->appendHTML('Restoring key "' . $name . '". Type: ' . gettype($res) . '.');
+ }
+ else {
+ $res_display = strip_tags($res);
+
+ if (strlen($res_display) > 200) {
+ $res_display = substr($res_display, 0, 50) . ' ...';
+ }
+
+ $this->Application->Debugger->appendHTML('Restoring key "' . $name . '" resulted [' . $res_display . ']');
+ }
+ }
+
+ if ($store_locally && ($res !== false)) {
+ $this->_localStorage[$name] = $res;
+
+ if ($this->displayCacheStatistics) {
+ $this->setStatistics($name, $res);
+ }
+ }
+
+ return $res;
}
/**
- * Deletes cached $name value from cache named $cache_name
+ * Deletes value from cache
*
- * @param int $name key name from cache
+ * @param string $name
* @return mixed
*/
function delete($name)
{
- $this->_storage->delete($name);
+ $name = $this->prepareKeyName($name);
+ unset($this->_localStorage[$name]);
+
+ return $this->_handler->delete($name);
}
/**
- * Returns caching type of current storage engine
+ * Reset's all memory cache at once
+ */
+ function reset()
+ {
+ // don't check for enabled, because we maybe need to reset cache anyway
+ if ($this->cachingType == CACHING_TYPE_TEMPORARY) {
+ return ;
+ }
+
+ $site_key = $this->_cachePrefix(true);
+
+ $this->_handler->set($site_key, $this->_handler->get($site_key) + 1);
+ }
+
+ /**
+ * Replaces serials and adds unique site prefix to cache variable name
*
- * @return int
+ * @param string $name
+ * @param bool $replace_serials
+ * @return string
*/
- function getCachingType()
+ function prepareKeyName($name, $replace_serials = true)
{
- return $this->_storage->cachingType;
+ if ($this->cachingType == CACHING_TYPE_TEMPORARY) {
+ return $name;
+ }
+
+ // replace serials in key name
+ if ($replace_serials && preg_match_all('/\[%(.*?)%\]/', $name, $regs)) {
+ // [%LangSerial%] - prefix-wide serial in case of any change in "lang" prefix
+ // [%LangIDSerial:5%] - one id-wide serial in case of data, associated with given id was changed
+ // [%CiIDSerial:ItemResourceId:5%] - foreign key-based serial in case of data, associated with given foreign key was changed
+ foreach ($regs[1] as $serial_name) {
+ $name = str_replace('[%' . $serial_name . '%]', '[' . $serial_name . '=' . $this->getCache($serial_name, true, false) . ']', $name);
+ }
+ }
+
+ // add site-wide prefix to key
+ return $this->_cachePrefix() . $name;
}
+ /**
+ * Returns site-wide caching prefix
+ *
+ * @param bool $only_site_key_name
+ * @return string
+ */
+ function _cachePrefix($only_site_key_name = false)
+ {
+ // don't use SERVER_NAME here, because it may be cron, or command line request also
+ $site_key = 'site_serial:' . crc32(FULL_PATH);
+
+ if ($only_site_key_name) {
+ return $site_key;
+ }
+
+ $site_serial = $this->_handler->get($site_key);
+
+ if (!$site_serial) {
+ $site_serial = 1;
+ $this->_handler->set($site_key, $site_serial);
+ }
+
+ return "$site_key:$site_serial:";
+ }
+
function setStatistics($name, $found)
{
if (strpos($name, ']:') !== false) {
@@ -138,9 +282,19 @@
$this->statistics[$cache_name][$name][$status_key]++;
}
+ /**
+ * Returns storage size in bytes
+ *
+ * @return int
+ */
+ function getStorageSize()
+ {
+ return strlen( serialize($this->_localStorage) );
+ }
+
function printStatistics()
{
- $cache_size = $this->_storage->getStorageSize();
+ $cache_size = $this->getStorageSize();
$this->Application->Debugger->appendHTML('<strong>Cache Size:</strong> ' . formatSize($cache_size) . ' (' . $cache_size . ')');
@@ -157,105 +311,66 @@
}
}
- class CacheStorage extends Params {
+ class FakeCacheHandler {
+
var $cachingType = CACHING_TYPE_TEMPORARY;
- /**
- * Returns storage size in bytes
- *
- * @return int
- */
- function getStorageSize()
+ function FakeCacheHandler()
{
- return strlen( serialize($this->_Params) );
+
}
/**
- * Determines, that cache storage is working fine
+ * Retrieves value from cache
*
- * @return bool
+ * @param string $name
+ * @return mixed
*/
- function isWorking()
+ function get($name)
{
- return true;
+ return false;
}
- function _getKeyInfo($name)
- {
- if (strpos($name, ':') !== false) {
- list ($cache_name, $name) = explode(':', $name, 2);
- }
- else {
- $cache_name = '-';
- }
-
- return Array ($cache_name, $name);
- }
-
/**
- * Stores value to cache
+ * Stores value in cache
*
* @param string $name
* @param mixed $value
- * @param int $expires cache record expiration time in seconds
+ * @param int $expiration
+ * @return bool
*/
- function set($name, $value, $expires)
+ function set($name, $value, $expiration = 0)
{
- list ($cache_name, $name) = $this->_getKeyInfo($name);
-
- $cache = parent::Get($cache_name, Array());
- $cache[$name] = $value;
-
- parent::Set($cache_name, $cache);
+ return true;
}
/**
- * Returns value from cache
+ * Deletes key from cach
*
* @param string $name
- * @param bool $store_locally store data locally after retrieved
- * @return mixed
+ * @return bool
*/
- function get($name, $store_locally = false)
+ function delete($name)
{
- list ($cache_name, $name) = $this->_getKeyInfo($name);
-
- $cache = parent::Get($cache_name, Array());
- $ret = array_key_exists($name, $cache) ? $cache[$name] : false;
-
- return $ret;
+ return true;
}
/**
- * Deletes value from cache
+ * Determines, that cache storage is working fine
*
- * @param string $name
- * @return mixed
+ * @return bool
*/
- function delete($name)
+ function isWorking()
{
- list ($cache_name, $name) = $this->_getKeyInfo($name);
-
- $this->set($cache_name, $name, false, -3600);
+ return true;
}
-
- function reset()
- {
-
- }
}
- class MemcacheCacheStorage extends kBase {
- var $cachingType = CACHING_TYPE_MEMORY;
+ class MemcacheCacheHandler {
- /**
- * Part of what we retrieve will be stored locally (per script run) not to bother memcache a lot
- *
- * @var Array
- */
- var $_localStorage = Array ();
+ var $_enabled = false;
/**
* Memcache connection
@@ -264,14 +379,10 @@
*/
var $_handler = null;
- var $_enabled = false;
+ var $cachingType = CACHING_TYPE_MEMORY;
- var $_debugMode = false;
-
- function MemcacheCacheStorage()
+ function MemcacheCacheHandler()
{
- parent::kBase();
-
if (array_key_exists('MemcacheServers', $GLOBALS['vars'])) {
// for advanced users, who want to save one SQL on each page load
$memcached_servers = $GLOBALS['vars']['MemcacheServers'];
@@ -290,57 +401,47 @@
$this->_handler->addServer($server, $port);
}
- // try to set something to cache, if not working - set $this->Memcached to null
+ // verify, that memcache server is working
if (!$this->_handler->set('test', 1)) {
- $this->_handler = null;
$this->_enabled = false;
}
}
+ }
- $this->_debugMode = $this->Application->isDebugMode();
-
- if ($this->_debugMode) {
- $this->Application->Debugger->appendHTML('MemCache Enabled: ' . ($this->_enabled ? 'YES' : 'NO'));
- }
+ /**
+ * Retrieves value from cache
+ *
+ * @param string $name
+ * @return mixed
+ */
+ function get($name)
+ {
+ return $this->_handler->get($name);
}
/**
- * Returns storage size in bytes
+ * Stores value in cache
*
- * @return int
+ * @param string $name
+ * @param mixed $value
+ * @param int $expiration
+ * @return bool
*/
- function getStorageSize()
+ function set($name, $value, $expiration = 0)
{
- return strlen( serialize($this->_localStorage) );
+ // 0 - don't use compression
+ return $this->_handler->set($name, $value, 0, $expiration);
}
/**
- * Returns site-wide caching prefix
+ * Deletes key from cache
*
- * @param bool $only_site_key_name
- * @return string
+ * @param string $name
+ * @return bool
*/
- function _cachePrefix($only_site_key_name = false)
+ function delete($name)
{
- if (!$this->_enabled) {
- return false;
- }
-
- // don't use SERVER_NAME here, because it may be cron, or command line request also
- $site_key = 'site_serial:' . crc32(FULL_PATH);
-
- if ($only_site_key_name) {
- return $site_key;
- }
-
- $site_serial = $this->_handler->get($site_key);
-
- if (!$site_serial) {
- $site_serial = 1;
- $this->_handler->set($site_key, $site_serial);
- }
-
- return "$site_key:$site_serial:";
+ return $this->_handler->delete($name);
}
/**
@@ -352,121 +453,67 @@
{
return $this->_enabled;
}
+ }
- /**
- * Stores value to cache
- *
- * @param string $name
- * @param mixed $value
- * @param int $expires cache record expiration time in seconds
- */
- function set($name, $value, $expiration)
+
+ class ApcCacheHandler {
+
+ var $_enabled = false;
+
+ var $cachingType = CACHING_TYPE_MEMORY;
+
+ function ApcCacheHandler()
{
- if (!$this->_enabled) {
- return false;
+ $this->_enabled = function_exists('apc_fetch');
+
+ // verify, that apc is working
+ if ($this->_enabled && !$this->set('test', 1)) {
+ $this->_enabled = false;
}
-
- $name = $this->prepareKeyName($name);
- unset($this->_localStorage[$name]);
-
- // 0 - don't use compression
- return $this->_handler->set($name, $value, 0, $expiration);
}
/**
- * Returns value from cache
+ * Retrieves value from cache
*
* @param string $name
- * @param bool $store_locally store data locally after retrieved
- * @param bool $replace_serials
* @return mixed
*/
- function get($name, $store_locally = true, $replace_serials = true)
+ function get($name)
{
- if (!$this->_enabled) {
- return false;
- }
-
- $name = $this->prepareKeyName($name, $replace_serials);
-
- if ($store_locally) {
- if (array_key_exists($name, $this->_localStorage)) {
- return $this->_localStorage[$name];
- }
- }
-
- $res = $this->_handler->get($name);
-
- if ($replace_serials && $this->_debugMode) {
- // don't display subsequent serial cache retrievals (ones, that are part of keys)
- if (is_array($res)) {
- $this->Application->Debugger->appendHTML('Restoring key "' . $name . '". Type: ' . gettype($res) . '.');
- }
- else {
- $res_display = strip_tags($res);
-
- if (strlen($res_display) > 200) {
- $res_display = substr($res_display, 0, 50) . ' ...';
- }
-
- $this->Application->Debugger->appendHTML('Restoring key "' . $name . '" resulted [' . $res_display . ']');
- }
- }
-
- $this->_localStorage[$name] = $res;
-
- return $res;
+ return apc_fetch($name);
}
/**
- * Replaces serials in cache variable name
+ * Stores value in cache
*
* @param string $name
- * @param bool $replace_serials
- * @return string
+ * @param mixed $value
+ * @param int $expiration
+ * @return bool
*/
- function prepareKeyName($name, $replace_serials = true)
+ function set($name, $value, $expiration = 0)
{
- // replace serials in key name
- if ($replace_serials && preg_match_all('/\[%(.*?)%\]/', $name, $regs)) {
- // [%LangSerial%] - prefix-wide serial in case of any change in "lang" prefix
- // [%LangIDSerial:5%] - one id-wide serial in case of data, associated with given id was changed
- // [%CiIDSerial:ItemResourceId:5%] - foreign key-based serial in case of data, associated with given foreign key was changed
- foreach ($regs[1] as $serial_name) {
- $name = str_replace('[%' . $serial_name . '%]', '[' . $serial_name . '=' . $this->get($serial_name, true, false) . ']', $name);
- }
- }
-
- // add site-wide prefix to key
- return $this->_cachePrefix() . $name;
+ return apc_store($name, $value, $expiration);
}
/**
- * Deletes value from cache
+ * Deletes key from cache
*
* @param string $name
- * @return mixed
+ * @return bool
*/
function delete($name)
{
- if (!$this->_enabled) {
- return false;
- }
-
- $name = $this->prepareKeyName($name);
- unset($this->_localStorage[$name]);
-
- return $this->_handler->delete($name);
+ return apc_delete($name);
}
/**
- * Reset's all memory cache at once
+ * Determines, that cache storage is working fine
+ *
+ * @return bool
*/
- function reset()
+ function isWorking()
{
- // don't check for enabled, because we maybe need to reset cache anyway
- $site_key = $this->_cachePrefix(true);
-
- $this->_handler->set($site_key, $this->_handler->get($site_key) + 1);
+ return $this->_enabled;
}
- }
+ }
\ No newline at end of file
apc_caching_support_addon.patch [^] (513 bytes) 2010-03-02 13:10
[Show Content]
Index: cache.php
===================================================================
--- cache.php (revision 13170)
+++ cache.php (working copy)
@@ -388,7 +388,8 @@
$memcached_servers = $GLOBALS['vars']['MemcacheServers'];
}
else {
- $memcached_servers = $this->Application->ConfigValue('MemcacheServers');
+ $application =& kApplication::Instance();
+ $memcached_servers = $application->ConfigValue('MemcacheServers');
}
if ($memcached_servers && class_exists('Memcache')) {
apc_caching_support_addon2.patch [^] (590 bytes) 2010-03-02 14:11
[Show Content]
Index: install.php
===================================================================
--- install.php (revision 13152)
+++ install.php (working copy)
@@ -996,7 +996,7 @@
{
if (($force || !in_array($this->currentStep, $this->skipApplicationSteps)) && !isset($this->Application)) {
// step is allowed for application usage & it was not initialized in previous step
- global $start, $debugger, $dbg_options;
+ global $start, $debugger, $dbg_options, $vars;
include_once(FULL_PATH.'/core/kernel/startup.php');
$this->Application =& kApplication::Instance();
|