From 9ce85275343be4992b2838b708a85377a752f228 Mon Sep 17 00:00:00 2001 From: Tomasz Narloch Date: Fri, 12 Aug 2016 01:30:18 +0200 Subject: [PATCH] Fix memcache storage, refresh code --- libraries/joomla/cache/storage/memcache.php | 158 ++++++-------------- 1 file changed, 46 insertions(+), 112 deletions(-) diff --git a/libraries/joomla/cache/storage/memcache.php b/libraries/joomla/cache/storage/memcache.php index d8e35d5751a25..13d9d63048381 100644 --- a/libraries/joomla/cache/storage/memcache.php +++ b/libraries/joomla/cache/storage/memcache.php @@ -31,7 +31,7 @@ class JCacheStorageMemcache extends JCacheStorage * @var boolean * @since 11.1 */ - protected $_persistent = false; + protected static $_persistent = false; /** * Payload compression level @@ -39,7 +39,7 @@ class JCacheStorageMemcache extends JCacheStorage * @var integer * @since 11.1 */ - protected $_compress = 0; + protected static $_compress = 0; /** * Constructor @@ -52,7 +52,7 @@ public function __construct($options = array()) { parent::__construct($options); - if (static::isSupported() && static::$_db === null) + if (static::$_db === null) { $this->getConnection(); } @@ -68,28 +68,36 @@ public function __construct($options = array()) */ protected function getConnection() { - $config = JFactory::getConfig(); - $this->_persistent = $config->get('memcache_persist', true); - $this->_compress = $config->get('memcache_compress', false) == false ? 0 : MEMCACHE_COMPRESSED; + if (!static::isSupported()) + { + throw new RuntimeException('Memcache Extension is not available'); + } + + $config = JFactory::getConfig(); + + $host = $config->get('memcache_server_host', 'localhost'); + $port = $config->get('memcache_server_port', 11211); // Create the memcache connection static::$_db = new Memcache; - static::$_db->addserver($config->get('memcache_server_host', 'localhost'), $config->get('memcache_server_port', 11211), $this->_persistent); - $memcachetest = @static::$_db->connect($server['host'], $server['port']); + // If memcache object is static then $_persistent and $_compress too + static::$_persistent = $config->get('memcache_persist', true); + static::$_compress = $config->get('memcache_compress', false) ? MEMCACHE_COMPRESSED : 0; - if ($memcachetest == false) + if (static::$_persistent) { - throw new RuntimeException('Could not connect to memcache server', 404); + $result = @static::$_db->pconnect($host, $port); } - - // Memcahed has no list keys, we do our own accounting, initialise key index - if (static::$_db->get($this->_hash . '-index') === false) + else { - static::$_db->set($this->_hash . '-index', array(), $this->_compress, 0); + $result = @static::$_db->connect($host, $port); } - return; + if (!$result) + { + throw new RuntimeException('Could not connect to memcache server'); + } } /** @@ -177,25 +185,17 @@ public function store($id, $group, $data) } $index = static::$_db->get($this->_hash . '-index'); - - if ($index === false) - { - $index = array(); - } + $index = $index ? $index : array(); $tmparr = new stdClass; $tmparr->name = $cache_id; $tmparr->size = strlen($data); $index[] = $tmparr; - static::$_db->replace($this->_hash . '-index', $index, 0, 0); + static::$_db->set($this->_hash . '-index', $index, 0, 0); $this->unlockindex(); - // Prevent double writes, write only if it doesn't exist else replace - if (!static::$_db->replace($cache_id, $data, $this->_compress, $this->_lifetime)) - { - static::$_db->set($cache_id, $data, $this->_compress, $this->_lifetime); - } + static::$_db->set($cache_id, $data, static::$_compress, $this->_lifetime); return true; } @@ -220,25 +220,19 @@ public function remove($id, $group) } $index = static::$_db->get($this->_hash . '-index'); - - if ($index === false) - { - $index = array(); - } + $index = $index ? $index : array(); foreach ($index as $key => $value) { if ($value->name == $cache_id) { unset($index[$key]); + static::$_db->set($this->_hash . '-index', $index, 0, 0); + break; } - - break; } - static::$_db->replace($this->_hash . '-index', $index, 0, 0); $this->unlockindex(); - return static::$_db->delete($cache_id); } @@ -264,23 +258,22 @@ public function clean($group, $mode = null) $index = static::$_db->get($this->_hash . '-index'); - if ($index === false) + if ($index !== false) { - $index = array(); - } + $secret = $this->_hash; - $secret = $this->_hash; - - foreach ($index as $key => $value) - { - if (strpos($value->name, $secret . '-cache-' . $group . '-') === 0 xor $mode != 'group') + foreach ($index as $key => $value) { - static::$_db->delete($value->name, 0); - unset($index[$key]); + if (strpos($value->name, $secret . '-cache-' . $group . '-') === 0 xor $mode != 'group') + { + static::$_db->delete($value->name); + unset($index[$key]); + } } + + static::$_db->set($this->_hash . '-index', $index, 0, 0); } - static::$_db->replace($this->_hash . '-index', $index, 0, 0); $this->unlockindex(); return true; @@ -295,19 +288,7 @@ public function clean($group, $mode = null) */ public static function isSupported() { - // First check if the PHP requirements are met - $supported = extension_loaded('memcache') && class_exists('Memcache'); - - if (!$supported) - { - return false; - } - - // Now check if we can connect to the specified Memcache server - $config = JFactory::getConfig(); - - $memcache = new Memcache; - return @$memcache->connect($config->get('memcache_server_host', 'localhost'), $config->get('memcache_server_port', 11211)); + return extension_loaded('memcache') && class_exists('Memcache'); } /** @@ -330,27 +311,7 @@ public function lock($id, $group, $locktime) $cache_id = $this->_getCacheId($id, $group); - if (!$this->lockindex()) - { - return false; - } - - $index = static::$_db->get($this->_hash . '-index'); - - if ($index === false) - { - $index = array(); - } - - $tmparr = new stdClass; - $tmparr->name = $cache_id; - $tmparr->size = 1; - - $index[] = $tmparr; - static::$_db->replace($this->_hash . '-index', $index, 0, 0); - $this->unlockindex(); - - $data_lock = static::$_db->add($cache_id . '_lock', 1, false, $locktime); + $data_lock = static::$_db->add($cache_id . '_lock', 1, 0, $locktime); if ($data_lock === false) { @@ -361,15 +322,15 @@ public function lock($id, $group, $locktime) { if ($lock_counter > $looptime) { - $returning->locked = false; - $returning->locklooped = true; break; } usleep(100); - $data_lock = static::$_db->add($cache_id . '_lock', 1, false, $locktime); + $data_lock = static::$_db->add($cache_id . '_lock', 1, 0, $locktime); $lock_counter++; } + + $returning->locklooped = true; } $returning->locked = $data_lock; @@ -390,32 +351,6 @@ public function lock($id, $group, $locktime) public function unlock($id, $group = null) { $cache_id = $this->_getCacheId($id, $group) . '_lock'; - - if (!$this->lockindex()) - { - return false; - } - - $index = static::$_db->get($this->_hash . '-index'); - - if ($index === false) - { - $index = array(); - } - - foreach ($index as $key => $value) - { - if ($value->name == $cache_id) - { - unset($index[$key]); - } - - break; - } - - static::$_db->replace($this->_hash . '-index', $index, 0, 0); - $this->unlockindex(); - return static::$_db->delete($cache_id); } @@ -429,7 +364,7 @@ public function unlock($id, $group = null) protected function lockindex() { $looptime = 300; - $data_lock = static::$_db->add($this->_hash . '-index_lock', 1, false, 30); + $data_lock = static::$_db->add($this->_hash . '-index_lock', 1, 0, 30); if ($data_lock === false) { @@ -441,11 +376,10 @@ protected function lockindex() if ($lock_counter > $looptime) { return false; - break; } usleep(100); - $data_lock = static::$_db->add($this->_hash . '-index_lock', 1, false, 30); + $data_lock = static::$_db->add($this->_hash . '-index_lock', 1, 0, 30); $lock_counter++; } }