From 32812c94823c70f3af25b0f942084d4d27a0b564 Mon Sep 17 00:00:00 2001 From: Miguel Dantas Date: Thu, 15 Aug 2019 16:05:33 +0100 Subject: [PATCH] [PLUGINS] Updated and reviewed the Memcached plugin --- plugins/Memcached/MemcachedPlugin.php | 149 +++++++++++++++----------- plugins/Memcached/README | 31 ++++-- 2 files changed, 109 insertions(+), 71 deletions(-) diff --git a/plugins/Memcached/MemcachedPlugin.php b/plugins/Memcached/MemcachedPlugin.php index 25ca4ca77b..1b94c4b5da 100644 --- a/plugins/Memcached/MemcachedPlugin.php +++ b/plugins/Memcached/MemcachedPlugin.php @@ -1,13 +1,15 @@ . * * @category Cache - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @author Craig Andrews + * @author Miguel Dantas * @copyright 2009 StatusNet, Inc. - * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org + * @copyright 2009, 2019 Free Software Foundation, Inc http://www.fsf.org * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ -if (!defined('STATUSNET')) { - // This check helps protect against security problems; - // your code file can't be executed directly from the web. - exit(1); -} +defined('GNUSOCIAL') || die(); -/** - * A plugin to use memcached for the cache interface - * - * This used to be encoded as config-variable options in the core code; - * it's now broken out to a separate plugin. The same interface can be - * implemented by other plugins. - * - * @category Cache - * @package StatusNet - * @author Evan Prodromou - * @author Craig Andrews - * @copyright 2009 StatusNet, Inc. - * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - */ class MemcachedPlugin extends Plugin { - const PLUGIN_VERSION = '2.0.0'; + const PLUGIN_VERSION = '2.1.0'; static $cacheInitialized = false; - private $_conn = null; - public $servers = array('127.0.0.1;11211'); - + public $servers = ['127.0.0.1']; public $defaultExpiry = 86400; // 24h + private $_conn = null; + /** * Initialize the plugin * @@ -72,8 +55,12 @@ class MemcachedPlugin extends Plugin */ function onInitializePlugin() { - $this->_ensureConn(); - self::$cacheInitialized = true; + try { + $this->_ensureConn(); + self::$cacheInitialized = true; + } catch (MemcachedException $e) { + common_log(LOG_ERR, 'Memcached encountered exception ' . get_class($e) . ': ' . $e->getMessage()); + } return true; } @@ -89,9 +76,19 @@ class MemcachedPlugin extends Plugin */ function onStartCacheGet(&$key, &$value) { - $this->_ensureConn(); - $value = $this->_conn->get($key); - return false; + try { + $this->_ensureConn(); + $value = $this->_conn->get($key); + } catch (MemcachedException $e) { + common_log(LOG_ERR, 'Memcached encountered exception ' . get_class($e) . ': ' . $e->getMessage()); + return true; + } + if ($value === false) { + // If not found, let other plugins handle it + return $this->_conn->getResultCode() === Memcached::RES_NOTFOUND; + } else { + return false; + } } /** @@ -107,12 +104,17 @@ class MemcachedPlugin extends Plugin */ function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success) { - $this->_ensureConn(); if ($expiry === null) { $expiry = $this->defaultExpiry; } - $success = $this->_conn->set($key, $value, $expiry); - return false; + try { + $this->_ensureConn(); + $success = $this->_conn->set($key, $value, $expiry); + } catch (MemcachedException $e) { + common_log(LOG_ERR, 'Memcached encountered exception ' . get_class($e) . ': ' . $e->getMessage()); + return true; + } + return !$success; } /** @@ -127,9 +129,19 @@ class MemcachedPlugin extends Plugin */ function onStartCacheIncrement(&$key, &$step, &$value) { - $this->_ensureConn(); - $value = $this->_conn->increment($key, $step); - return false; + try { + $this->_ensureConn(); + $value = $this->_conn->increment($key, $step); + } catch (MemcachedException $e) { + common_log(LOG_ERR, 'Memcached encountered exception ' . get_class($e) . ': ' . $e->getMessage()); + return true; + } + if ($value === false) { + // If not found, let other plugins handle it + return $this->_conn->getResultCode() === Memcached::RES_NOTFOUND; + } else { + return false; + } } /** @@ -142,14 +154,23 @@ class MemcachedPlugin extends Plugin */ function onStartCacheDelete(&$key, &$success) { - $this->_ensureConn(); - $success = $this->_conn->delete($key); - return false; + try { + $this->_ensureConn(); + $success = $this->_conn->delete($key); + } catch (MemcachedException $e) { + common_log(LOG_ERR, 'Memcached encountered exception ' . get_class($e) . ': ' . $e->getMessage()); + return true; + } + return !$success; } function onStartCacheReconnect(&$success) { - // nothing to do + try { + $this->_ensureConn(); + } catch (MemcachedException $e) { + common_log(LOG_ERR, 'Memcached encountered exception ' . get_class($e) . ': ' . $e->getMessage()); + } return true; } @@ -167,28 +188,28 @@ class MemcachedPlugin extends Plugin $this->_conn = new Memcached(common_config('site', 'nickname')); if (!count($this->_conn->getServerList())) { - if (is_array($this->servers)) { - $servers = $this->servers; - } else { - $servers = array($this->servers); - } - foreach ($servers as $server) { - if (strpos($server, ';') !== false) { - list($host, $port) = explode(';', $server); + if (is_array($this->servers)) { + $servers = $this->servers; } else { - $host = $server; - $port = 11211; + $servers = [$this->servers]; + } + foreach ($servers as $server) { + if (is_array($server) && count($server) === 2) { + list($host, $port) = $server; + } else { + $host = is_array($server) ? $server[0] : $server; + $port = 11211; + } + + $this->_conn->addServer($host, $port); } - $this->_conn->addServer($host, $port); - } + // Compress items stored in the cache. - // Compress items stored in the cache. + // Allows the cache to store objects larger than 1MB (if they + // compress to less than 1MB), and improves cache memory efficiency. - // Allows the cache to store objects larger than 1MB (if they - // compress to less than 1MB), and improves cache memory efficiency. - - $this->_conn->setOption(Memcached::OPT_COMPRESSION, true); + $this->_conn->setOption(Memcached::OPT_COMPRESSION, true); } } } diff --git a/plugins/Memcached/README b/plugins/Memcached/README index 05ae884b02..0bfcd4cbbe 100644 --- a/plugins/Memcached/README +++ b/plugins/Memcached/README @@ -2,20 +2,37 @@ The Memcached plugin implements cache interface for memcached. See: http://memcached.org/ +The difference between the former `MemcachePlugin` and `MemcachedPlugin` is that they use, +respectively, `memcache` and `memcached` as the underlying php libraries. These are similar +libraries, made by different authors with slightly different cacpabilities, therefore `memcached` +was selected. + Installation ============ -add "addPlugin('Memcached');" -to the bottom of your config.php + +Tell your `config.php` to use this plugin (replace `tcp://localhost:6379` with the address/port +of your Memcache backend server): + +`addPlugin('Memcached');` + +Note that this typically requires configuring the `memcached` extension for `php`, which is +typically available as a binary package from your system's package manager. In Debian based systems +and on Arch based systems, this is likely available under the `php-memcached` package. Note the +final `d`. On Arch, uncomment the line in `/etc/php/conf.d/memcached.ini` and restart your webserver +and/or php-fpm or similar. Settings ======== -servers: Array of memcached servers addresses + +servers: Array of memcached servers addresses. Each server address should be either a string with +address or an array where the first element is a string with the address an optional second element +with the port. + defaultExpiry: How long before cache expires (in seconds) Example ======= -addPlugin('Memcached', array( - 'servers' => array('127.0.0.1;11211'), - 'defaultExpiry' => 86400 // 24h -)); +addPlugin('Memcached', [ 'servers' => ['127.0.0.1', 11211], + 'defaultExpiry' => 86400 // 24h + ]);