Remove Memcached support
authorTim Düsterhus <duesterhus@woltlab.com>
Fri, 5 Aug 2022 08:00:47 +0000 (10:00 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Fri, 5 Aug 2022 08:00:47 +0000 (10:00 +0200)
While Memcached is only deprecated since 5.4, it also is effectively
unmaintained and untested since longer than that.

The Disk cache works fine for the vast majority of users and Redis is available
for the others and even more featureful compared to Memcached.

Resolves #3642

com.woltlab.wcf/option.xml
constants.php
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.6_checkCache.php [new file with mode: 0644]
wcfsetup/install/files/lib/acp/page/CacheListPage.class.php
wcfsetup/install/files/lib/acp/page/SystemCheckPage.class.php
wcfsetup/install/files/lib/system/cache/source/MemcachedCacheSource.class.php [deleted file]
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 59c1d82e4d48f7fead359a4d26af4ccb2a22ad55..cf9b740e208a8be54e7d4b9eaf5eb088cc9b6784 100644 (file)
@@ -94,9 +94,6 @@
                        <category name="general.cache.general">
                                <parent>general.cache</parent>
                        </category>
-                       <category name="general.cache.memcached">
-                               <parent>general.cache</parent>
-                       </category>
                        <category name="general.cache.redis">
                                <parent>general.cache</parent>
                        </category>
@@ -885,17 +882,11 @@ encrypt:wcf.acp.option.mail_smtp_starttls.encrypt</selectoptions>
                                <categoryname>general.cache.general</categoryname>
                                <optiontype>radioButton</optiontype>
                                <defaultvalue>disk</defaultvalue>
-                               <enableoptions>disk:!cache_source_memcached_host,!cache_source_redis_host
-memcached:cache_source_memcached_host,!cache_source_redis_host
-redis:cache_source_redis_host,!cache_source_memcached_host</enableoptions>
+                               <enableoptions>disk:!cache_source_redis_host
+redis:cache_source_redis_host</enableoptions>
                                <selectoptions>disk:wcf.acp.option.cache_source_type.disk
-memcached:wcf.acp.option.cache_source_type.memcached
 redis:wcf.acp.option.cache_source_type.redis</selectoptions>
                        </option>
-                       <option name="cache_source_memcached_host">
-                               <categoryname>general.cache.memcached</categoryname>
-                               <optiontype>textarea</optiontype>
-                       </option>
                        <option name="cache_source_redis_host">
                                <categoryname>general.cache.redis</categoryname>
                                <optiontype>text</optiontype>
@@ -1650,5 +1641,6 @@ DESC:wcf.global.sortOrder.descending</selectoptions>
        <delete>
                <option name="desktop_notification_package_id"/>
                <option name="http_send_x_frame_options"/>
+               <option name="cache_source_memcached_host"/>
        </delete>
 </data>
index f246e953589423c74d6188d9b367019cb0ece4e1..59ab3ba6cbc2c039f333b14345cca18e4b7a0037 100644 (file)
@@ -96,7 +96,6 @@
 \define('MAIL_SMTP_PASSWORD', '');
 \define('MAIL_USE_F_PARAM', 1);
 \define('CACHE_SOURCE_TYPE', 'disk');
-\define('CACHE_SOURCE_MEMCACHED_HOST', '');
 \define('CACHE_SOURCE_REDIS_HOST', '');
 \define('AVAILABLE_PAYMENT_METHODS', '');
 \define('PAYPAL_EMAIL_ADDRESS', '');
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.6_checkCache.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.6_checkCache.php
new file mode 100644 (file)
index 0000000..59aeeb9
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * Checks for Memcached as the configured cache.
+ *
+ * @author  Tim Duesterhus
+ * @copyright   2001-2022 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core
+ */
+
+use wcf\system\WCF;
+
+if (CACHE_SOURCE_TYPE === 'memcached') {
+    if (WCF::getLanguage()->getFixedLanguageCode() === 'de') {
+        $message = "Die Unterst&uuml;tzung für Memcached wird mit dem Upgrade entfernt. Es ist notwendig, auf einen anderen Cache umzustellen.";
+    } else {
+        $message = "The support for Memcached will be removed during the upgrade. It is required to configure a different cache.";
+    }
+
+    throw new \RuntimeException($message);
+}
index 5b8f84ddf957727064fe8c40b5bf0c7efd9951ec..2ffec9d75df370be3c98d20e1f3b4e1e994e268d 100755 (executable)
@@ -83,12 +83,6 @@ class CacheListPage extends AbstractPage
                 $this->readCacheFiles('data', WCF_DIR . 'cache');
                 break;
 
-            case 'wcf\system\cache\source\MemcachedCacheSource':
-                // set version
-                /** @noinspection PhpUndefinedMethodInspection */
-                $this->cacheData['version'] = CacheHandler::getInstance()->getCacheSource()->getMemcachedVersion();
-                break;
-
             case 'wcf\system\cache\source\RedisCacheSource':
                 // set version
                 /** @noinspection PhpUndefinedMethodInspection */
index a4ed505a47f23126a9d8ee76cb52ba8b9d82e201..019369c3100b94c161fb8d6bb8fe28cca340f66a 100644 (file)
@@ -176,10 +176,6 @@ class SystemCheckPage extends AbstractPage
             $this->phpExtensions[] = 'imagick';
         }
 
-        if (CACHE_SOURCE_TYPE === 'memcached' && !\in_array('memcached', $this->phpExtensions)) {
-            $this->phpExtensions[] = 'memcached';
-        }
-
         if (CACHE_SOURCE_TYPE === 'redis' && !\in_array('redis', $this->phpExtensions)) {
             $this->phpExtensions[] = 'redis';
         }
diff --git a/wcfsetup/install/files/lib/system/cache/source/MemcachedCacheSource.class.php b/wcfsetup/install/files/lib/system/cache/source/MemcachedCacheSource.class.php
deleted file mode 100644 (file)
index 4cca456..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-<?php
-
-namespace wcf\system\cache\source;
-
-use wcf\system\exception\SystemException;
-use wcf\system\Regex;
-use wcf\system\WCF;
-use wcf\util\StringUtil;
-
-/**
- * MemcachedCacheSource is an implementation of CacheSource that uses a Memcached server to store cached variables.
- *
- * @author  Tim Duesterhus, Alexander Ebert
- * @copyright   2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Cache\Source
- * @deprecated  5.4 - Memcached is deprecated in favor of Redis if a distributed in-memory cache is required.
- */
-class MemcachedCacheSource implements ICacheSource
-{
-    /**
-     * memcached object
-     * @var \Memcached
-     */
-    protected $memcached;
-
-    /**
-     * Creates a new instance of memcached.
-     */
-    public function __construct()
-    {
-        if (!\class_exists('Memcached')) {
-            throw new SystemException('memcached support is not enabled.');
-        }
-        if (!\defined('\Memcached::OPT_REMOVE_FAILED_SERVERS')) {
-            throw new SystemException('required \Memcached::OPT_REMOVE_FAILED_SERVERS option is not available');
-        }
-
-        // init memcached
-        $this->memcached = new \Memcached();
-
-        // disable broken hosts for the remainder of the execution
-        // Note: This may cause outdated entries once the affected memcached
-        // server comes back online. But it is better than completely bailing out.
-        // If the outage wasn't solely related to networking the cache is flushed
-        // on restart of the affected memcached instance anyway.
-        $this->memcached->setOption(\Memcached::OPT_REMOVE_FAILED_SERVERS, 1);
-
-        // LIBKETAMA_COMPATIBLE uses consistent hashing, which causes fewer remaps
-        // in case a server is added or removed.
-        $this->memcached->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
-
-        $this->memcached->setOption(\Memcached::OPT_PREFIX_KEY, WCF_UUID . '_');
-
-        if (!WCF::debugModeIsEnabled()) {
-            // use the more efficient binary protocol to communicate with the memcached instance
-            // this option is disabled in debug mode to allow for easier debugging
-            // with tools, such as strace(1)
-            $this->memcached->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
-        }
-
-        // add servers
-        $tmp = \explode("\n", StringUtil::unifyNewlines(CACHE_SOURCE_MEMCACHED_HOST));
-        $servers = [];
-        $defaultWeight = \floor(100 / \count($tmp));
-        $regex = new Regex('^\[([a-z0-9\:\.]+)\](?::([0-9]{1,5}))?(?::([0-9]{1,3}))?$', Regex::CASE_INSENSITIVE);
-
-        foreach ($tmp as $server) {
-            $server = StringUtil::trim($server);
-            if (!empty($server)) {
-                $host = $server;
-                $port = 11211; // default memcached port
-                $weight = $defaultWeight;
-
-                // check for IPv6
-                if ($regex->match($host)) {
-                    $matches = $regex->getMatches();
-                    $host = $matches[1];
-                    if (isset($matches[2])) {
-                        $port = $matches[2];
-                    }
-                    if (isset($matches[3])) {
-                        $weight = $matches[3];
-                    }
-                } else {
-                    // IPv4, try to get port and weight
-                    if (\strpos($host, ':')) {
-                        $parsedHost = \explode(':', $host);
-                        $host = $parsedHost[0];
-                        $port = $parsedHost[1];
-
-                        if (isset($parsedHost[2])) {
-                            $weight = $parsedHost[2];
-                        }
-                    }
-                }
-
-                $servers[] = [$host, $port, $weight];
-            }
-        }
-        $this->memcached->addServers($servers);
-
-        // test connection, set will fail if no memcached instances are available
-        // if only the target for the 'connection_testing' key is unavailable the
-        // requests will automatically be mapped to another server
-        if (!$this->memcached->set('connection_testing', true)) {
-            throw new SystemException('Unable to obtain any valid connection');
-        }
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function flush($cacheName, $useWildcard)
-    {
-        if ($useWildcard) {
-            $this->memcached->add('_flush_' . $cacheName, TIME_NOW);
-            $this->memcached->increment('_flush_' . $cacheName);
-        }
-
-        $this->memcached->delete($this->getCacheName($cacheName));
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function flushAll()
-    {
-        // increment flush counter to nuke all data
-        $this->memcached->add('_flush', TIME_NOW);
-        $this->memcached->increment('_flush');
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function get($cacheName, $maxLifetime)
-    {
-        $value = $this->memcached->get($this->getCacheName($cacheName));
-
-        if ($value === false) {
-            // check if value does not exist
-            if ($this->memcached->getResultCode() !== \Memcached::RES_SUCCESS) {
-                return;
-            }
-        }
-
-        return $value;
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function set($cacheName, $value, $maxLifetime)
-    {
-        $this->memcached->set($this->getCacheName($cacheName), $value, $this->getTTL($maxLifetime));
-    }
-
-    /**
-     * Returns time to live in seconds, defaults to 3 days.
-     *
-     * @param int $maxLifetime
-     * @return  int
-     */
-    protected function getTTL($maxLifetime = 0)
-    {
-        // max lifetime is a timestamp -> http://www.php.net/manual/en/memcached.expiration.php
-        if ($maxLifetime && ($maxLifetime <= (60 * 60 * 24 * 30) || $maxLifetime >= TIME_NOW)) {
-            return $maxLifetime;
-        }
-
-        // default TTL: 3 days
-        return 60 * 60 * 24 * 3;
-    }
-
-    /**
-     * Returns the name for the given cache name in respect to flush count.
-     *
-     * @param string $cacheName
-     * @return  string
-     */
-    protected function getCacheName($cacheName)
-    {
-        $parts = \explode('-', $cacheName, 2);
-
-        $flush = $this->memcached->get('_flush');
-
-        // create flush counter if it does not exist
-        if ($flush === false) {
-            $this->memcached->add('_flush', TIME_NOW);
-            $flush = $this->memcached->get('_flush');
-        }
-
-        // the cache specific flush counter only is of interest if the cache name contains parameters
-        // the version without parameters is deleted explicitly when calling flush
-        // this saves us a memcached query in most cases (caches without any parameters)
-        if (isset($parts[1])) {
-            $flushByCache = $this->memcached->get('_flush_' . $parts[0]);
-
-            // create flush counter if it does not exist
-            if ($flushByCache === false) {
-                $this->memcached->add('_flush_' . $parts[0], TIME_NOW);
-                $flushByCache = $this->memcached->get('_flush_' . $parts[0]);
-            }
-
-            $flush .= '_' . $flushByCache;
-        }
-
-        return $flush . '_' . $cacheName;
-    }
-
-    /**
-     * Returns the Memcached server version
-     *
-     * @return  string
-     */
-    public function getMemcachedVersion()
-    {
-        $versions = $this->memcached->getVersion();
-
-        return \reset($versions);
-    }
-}
index 76c3cbffc7f51896254d51895d01b7492c39c318..221f857e3fb7c66d6e9e9d3eed4bd1707b7169d7 100644 (file)
                <item name="wcf.acp.cache.list.perm"><![CDATA[Zugriffsrechte]]></item>
                <item name="wcf.acp.cache.list.size"><![CDATA[Größe]]></item>
                <item name="wcf.acp.cache.source.type.DiskCacheSource"><![CDATA[Dateisystem]]></item>
-               <item name="wcf.acp.cache.source.type.MemcachedCacheSource"><![CDATA[Memcached (veraltet / nicht empfohlen)]]></item>
                <item name="wcf.acp.cache.source.type.RedisCacheSource"><![CDATA[Redis]]></item>
                <item name="wcf.acp.cache.type.data"><![CDATA[Daten]]></item>
                <item name="wcf.acp.cache.type.language"><![CDATA[Sprachen]]></item>
@@ -1253,20 +1252,15 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.notice.showOrder.description"><![CDATA[Legt die Reihenfolge fest, in der die Hinweise angezeigt werden.]]></item>
        </category>
        <category name="wcf.acp.option">
-               <item name="wcf.acp.option.cache_source_memcached_host"><![CDATA[Memcached-Server]]></item>
-               <item name="wcf.acp.option.cache_source_memcached_host.description"/>
                <item name="wcf.acp.option.cache_source_redis_host"><![CDATA[Redis-Server]]></item>
                <item name="wcf.acp.option.cache_source_redis_host.description"><![CDATA[Die Adresse des Servers, zum Beispiel „localhost“ oder „10.0.13.37:1337“.]]></item>
                <item name="wcf.acp.option.cache_source_type"><![CDATA[Cache-Methode]]></item>
                <item name="wcf.acp.option.cache_source_type.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Beachte{else}Beachten Sie{/if}, dass einige Methoden spezielle Anforderungen an das Server-System stellen und nicht auf jedem Server zur Verfügung stehen.]]></item>
                <item name="wcf.acp.option.cache_source_type.disk"><![CDATA[Dateisystem (Standard)]]></item>
-               <item name="wcf.acp.option.cache_source_type.memcached"><![CDATA[Memcached (veraltet / nicht empfohlen)]]></item>
                <item name="wcf.acp.option.cache_source_type.redis"><![CDATA[Redis]]></item>
                <item name="wcf.acp.option.category.general"><![CDATA[Allgemein]]></item>
                <item name="wcf.acp.option.category.general.cache"><![CDATA[Cache]]></item>
                <item name="wcf.acp.option.category.general.cache.general"><![CDATA[Allgemein]]></item>
-               <item name="wcf.acp.option.category.general.cache.memcached"><![CDATA[Memcached (veraltet / nicht empfohlen)]]></item>
-               <item name="wcf.acp.option.category.general.cache.memcached.description"><![CDATA[Die Unterstützung für Memcached ist veraltet und wird in einer zukünftigen Version von WoltLab Suite™ entfernt. Benutzern von Memcached wird empfohlen auf Redis zu wechseln.]]></item>
                <item name="wcf.acp.option.category.general.cache.redis"><![CDATA[Redis]]></item>
                <item name="wcf.acp.option.category.general.cache.redis.description"><![CDATA[Redis speichert häufig benötigte Daten im Arbeitsspeicher zwischen. Dies kann die Last auf die Datenbank und das Dateisystem drastisch reduzieren. {if LANGUAGE_USE_INFORMAL_VARIANT}Lies{else}Lesen Sie{/if} mehr über dieses Thema auf der folgenden Seite: <a href="https://redis.io/" class="externalURL">redis.io</a>.]]></item>
                <item name="wcf.acp.option.category.general.system.date"><![CDATA[Datum &amp; Zeit]]></item>
@@ -5567,5 +5561,11 @@ Benachrichtigungen auf <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|phra
        <item name="wcf.acp.index.system.php.sslSupport.notAvailable"/>
        <item name="wcf.acp.option.http_send_x_frame_options"/>
        <item name="wcf.acp.option.http_send_x_frame_options.description"/>
+       <item name="wcf.acp.cache.source.type.MemcachedCacheSource"/>
+       <item name="wcf.acp.option.cache_source_memcached_host"/>
+       <item name="wcf.acp.option.cache_source_memcached_host.description"/>
+       <item name="wcf.acp.option.category.general.cache.memcached"/>
+       <item name="wcf.acp.option.category.general.cache.memcached.description"/>
+       <item name="wcf.acp.option.cache_source_type.memcached"/>
 </delete>
 </language>
index 352bee7c8c90cc2062d82fa9dfc79a06bfea5c16..472644d229ead327ad0c41e2c08df94871f620be 100644 (file)
                <item name="wcf.acp.cache.list.perm"><![CDATA[Permissions]]></item>
                <item name="wcf.acp.cache.list.size"><![CDATA[Size]]></item>
                <item name="wcf.acp.cache.source.type.DiskCacheSource"><![CDATA[Filesystem]]></item>
-               <item name="wcf.acp.cache.source.type.MemcachedCacheSource"><![CDATA[Memcached (Deprecated / Not Recommended)]]></item>
                <item name="wcf.acp.cache.source.type.RedisCacheSource"><![CDATA[Redis]]></item>
                <item name="wcf.acp.cache.type.data"><![CDATA[Data]]></item>
                <item name="wcf.acp.cache.type.language"><![CDATA[Languages]]></item>
@@ -1232,20 +1231,15 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.notice.showOrder.description"><![CDATA[Choose display order of notices.]]></item>
        </category>
        <category name="wcf.acp.option">
-               <item name="wcf.acp.option.cache_source_memcached_host"><![CDATA[Memcached-Server]]></item>
-               <item name="wcf.acp.option.cache_source_memcached_host.description"/>
                <item name="wcf.acp.option.cache_source_redis_host"><![CDATA[Redis-Server]]></item>
                <item name="wcf.acp.option.cache_source_redis_host.description"><![CDATA[The server’s address, for example “localhost” or “10.0.13.37:1337”.]]></item>
                <item name="wcf.acp.option.cache_source_type"><![CDATA[Caching Method]]></item>
                <item name="wcf.acp.option.cache_source_type.description"><![CDATA[Caching methods different from filesystem require special extensions or services running on your machine.]]></item>
                <item name="wcf.acp.option.cache_source_type.disk"><![CDATA[Use Filesystem (default)]]></item>
-               <item name="wcf.acp.option.cache_source_type.memcached"><![CDATA[Use Memcached (Deprecated / Not Recommended)]]></item>
                <item name="wcf.acp.option.cache_source_type.redis"><![CDATA[Use Redis]]></item>
                <item name="wcf.acp.option.category.general"><![CDATA[General]]></item>
                <item name="wcf.acp.option.category.general.cache"><![CDATA[Cache]]></item>
                <item name="wcf.acp.option.category.general.cache.general"><![CDATA[General]]></item>
-               <item name="wcf.acp.option.category.general.cache.memcached"><![CDATA[Memcached (Deprecated / Not Recommended)]]></item>
-               <item name="wcf.acp.option.category.general.cache.memcached.description"><![CDATA[The support for Memcached is deprecated and will be removed in a future version of WoltLab Suite™. Memcached users are encouraged to switch to Redis.]]></item>
                <item name="wcf.acp.option.category.general.cache.redis"><![CDATA[Redis]]></item>
                <item name="wcf.acp.option.category.general.cache.redis.description"><![CDATA[Redis uses the machine’s memory to store frequently accessed data, reducing database and filesystem load. Read more about Redis on <a href="https://redis.io/" class="externalURL">redis.io</a>.]]></item>
                <item name="wcf.acp.option.category.general.system.date"><![CDATA[Date and Time]]></item>
@@ -5569,5 +5563,10 @@ your notifications on <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|phras
        <item name="wcf.acp.index.system.php.sslSupport.notAvailable"/>
        <item name="wcf.acp.option.http_send_x_frame_options"/>
        <item name="wcf.acp.option.http_send_x_frame_options.description"/>
-</delete>
+       <item name="wcf.acp.cache.source.type.MemcachedCacheSource"/>
+       <item name="wcf.acp.option.cache_source_memcached_host"/>
+       <item name="wcf.acp.option.cache_source_memcached_host.description"/>
+       <item name="wcf.acp.option.category.general.cache.memcached"/>
+       <item name="wcf.acp.option.category.general.cache.memcached.description"/>
+       <item name="wcf.acp.option.cache_source_type.memcached"/></delete>
 </language>