mirror of
https://github.com/nextcloud/server.git
synced 2026-06-09 08:44:07 -04:00
fix: Add a factory for Memcached object instead of a static var
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
This commit is contained in:
parent
ac8cd6846d
commit
2aeac5ed7c
4 changed files with 100 additions and 72 deletions
|
|
@ -1939,6 +1939,7 @@ return array(
|
|||
'OC\\Memcache\\Factory' => $baseDir . '/lib/private/Memcache/Factory.php',
|
||||
'OC\\Memcache\\LoggerWrapperCache' => $baseDir . '/lib/private/Memcache/LoggerWrapperCache.php',
|
||||
'OC\\Memcache\\Memcached' => $baseDir . '/lib/private/Memcache/Memcached.php',
|
||||
'OC\\Memcache\\MemcachedFactory' => $baseDir . '/lib/private/Memcache/MemcachedFactory.php',
|
||||
'OC\\Memcache\\NullCache' => $baseDir . '/lib/private/Memcache/NullCache.php',
|
||||
'OC\\Memcache\\ProfilerWrapperCache' => $baseDir . '/lib/private/Memcache/ProfilerWrapperCache.php',
|
||||
'OC\\Memcache\\Redis' => $baseDir . '/lib/private/Memcache/Redis.php',
|
||||
|
|
|
|||
|
|
@ -1980,6 +1980,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OC\\Memcache\\Factory' => __DIR__ . '/../../..' . '/lib/private/Memcache/Factory.php',
|
||||
'OC\\Memcache\\LoggerWrapperCache' => __DIR__ . '/../../..' . '/lib/private/Memcache/LoggerWrapperCache.php',
|
||||
'OC\\Memcache\\Memcached' => __DIR__ . '/../../..' . '/lib/private/Memcache/Memcached.php',
|
||||
'OC\\Memcache\\MemcachedFactory' => __DIR__ . '/../../..' . '/lib/private/Memcache/MemcachedFactory.php',
|
||||
'OC\\Memcache\\NullCache' => __DIR__ . '/../../..' . '/lib/private/Memcache/NullCache.php',
|
||||
'OC\\Memcache\\ProfilerWrapperCache' => __DIR__ . '/../../..' . '/lib/private/Memcache/ProfilerWrapperCache.php',
|
||||
'OC\\Memcache\\Redis' => __DIR__ . '/../../..' . '/lib/private/Memcache/Redis.php',
|
||||
|
|
|
|||
|
|
@ -8,73 +8,18 @@
|
|||
|
||||
namespace OC\Memcache;
|
||||
|
||||
use OC\SystemConfig;
|
||||
use OCP\HintException;
|
||||
use OCP\IConfig;
|
||||
use OCP\IMemcache;
|
||||
use OCP\Server;
|
||||
|
||||
class Memcached extends Cache implements IMemcache {
|
||||
use CASTrait;
|
||||
|
||||
/**
|
||||
* @var \Memcached $cache
|
||||
*/
|
||||
private static $cache = null;
|
||||
private \Memcached $cache;
|
||||
|
||||
use CADTrait;
|
||||
|
||||
public function __construct($prefix = '') {
|
||||
parent::__construct($prefix);
|
||||
if (is_null(self::$cache)) {
|
||||
self::$cache = new \Memcached();
|
||||
|
||||
$defaultOptions = [
|
||||
\Memcached::OPT_CONNECT_TIMEOUT => 50,
|
||||
\Memcached::OPT_RETRY_TIMEOUT => 50,
|
||||
\Memcached::OPT_SEND_TIMEOUT => 50,
|
||||
\Memcached::OPT_RECV_TIMEOUT => 50,
|
||||
\Memcached::OPT_POLL_TIMEOUT => 50,
|
||||
|
||||
// Enable compression
|
||||
\Memcached::OPT_COMPRESSION => true,
|
||||
|
||||
// Turn on consistent hashing
|
||||
\Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
|
||||
|
||||
// Enable Binary Protocol
|
||||
\Memcached::OPT_BINARY_PROTOCOL => true,
|
||||
];
|
||||
/**
|
||||
* By default enable igbinary serializer if available
|
||||
*
|
||||
* Psalm checks depend on if igbinary is installed or not with memcached
|
||||
* @psalm-suppress RedundantCondition
|
||||
* @psalm-suppress TypeDoesNotContainType
|
||||
*/
|
||||
if (\Memcached::HAVE_IGBINARY) {
|
||||
$defaultOptions[\Memcached::OPT_SERIALIZER]
|
||||
= \Memcached::SERIALIZER_IGBINARY;
|
||||
}
|
||||
$options = Server::get(IConfig::class)->getSystemValue('memcached_options', []);
|
||||
if (is_array($options)) {
|
||||
$options = $options + $defaultOptions;
|
||||
self::$cache->setOptions($options);
|
||||
} else {
|
||||
throw new HintException("Expected 'memcached_options' config to be an array, got $options");
|
||||
}
|
||||
|
||||
$servers = Server::get(SystemConfig::class)->getValue('memcached_servers');
|
||||
if (!$servers) {
|
||||
$server = Server::get(SystemConfig::class)->getValue('memcached_server');
|
||||
if ($server) {
|
||||
$servers = [$server];
|
||||
} else {
|
||||
$servers = [['localhost', 11211]];
|
||||
}
|
||||
}
|
||||
self::$cache->addServers($servers);
|
||||
}
|
||||
$this->cache = \OCP\Server::get(MemcachedFactory::class)->getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -86,8 +31,8 @@ class Memcached extends Cache implements IMemcache {
|
|||
|
||||
#[\Override]
|
||||
public function get($key) {
|
||||
$result = self::$cache->get($this->getNameSpace() . $key);
|
||||
if ($result === false && self::$cache->getResultCode() === \Memcached::RES_NOTFOUND) {
|
||||
$result = $this->cache->get($this->getNameSpace() . $key);
|
||||
if ($result === false && $this->cache->getResultCode() === \Memcached::RES_NOTFOUND) {
|
||||
return null;
|
||||
} else {
|
||||
return $result;
|
||||
|
|
@ -97,29 +42,29 @@ class Memcached extends Cache implements IMemcache {
|
|||
#[\Override]
|
||||
public function set($key, $value, $ttl = 0) {
|
||||
if ($ttl > 0) {
|
||||
$result = self::$cache->set($this->getNameSpace() . $key, $value, $ttl);
|
||||
$result = $this->cache->set($this->getNameSpace() . $key, $value, $ttl);
|
||||
} else {
|
||||
$result = self::$cache->set($this->getNameSpace() . $key, $value);
|
||||
$result = $this->cache->set($this->getNameSpace() . $key, $value);
|
||||
}
|
||||
return $result || $this->isSuccess();
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function hasKey($key) {
|
||||
self::$cache->get($this->getNameSpace() . $key);
|
||||
return self::$cache->getResultCode() === \Memcached::RES_SUCCESS;
|
||||
$this->cache->get($this->getNameSpace() . $key);
|
||||
return $this->cache->getResultCode() === \Memcached::RES_SUCCESS;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function remove($key) {
|
||||
$result = self::$cache->delete($this->getNameSpace() . $key);
|
||||
return $result || $this->isSuccess() || self::$cache->getResultCode() === \Memcached::RES_NOTFOUND;
|
||||
$result = $this->cache->delete($this->getNameSpace() . $key);
|
||||
return $result || $this->isSuccess() || $this->cache->getResultCode() === \Memcached::RES_NOTFOUND;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function clear($prefix = '') {
|
||||
// Newer Memcached doesn't like getAllKeys(), flush everything
|
||||
self::$cache->flush();
|
||||
$this->cache->flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -133,7 +78,7 @@ class Memcached extends Cache implements IMemcache {
|
|||
*/
|
||||
#[\Override]
|
||||
public function add($key, $value, $ttl = 0) {
|
||||
$result = self::$cache->add($this->getPrefix() . $key, $value, $ttl);
|
||||
$result = $this->cache->add($this->getPrefix() . $key, $value, $ttl);
|
||||
return $result || $this->isSuccess();
|
||||
}
|
||||
|
||||
|
|
@ -147,9 +92,9 @@ class Memcached extends Cache implements IMemcache {
|
|||
#[\Override]
|
||||
public function inc($key, $step = 1) {
|
||||
$this->add($key, 0);
|
||||
$result = self::$cache->increment($this->getPrefix() . $key, $step);
|
||||
$result = $this->cache->increment($this->getPrefix() . $key, $step);
|
||||
|
||||
if (self::$cache->getResultCode() !== \Memcached::RES_SUCCESS) {
|
||||
if ($this->cache->getResultCode() !== \Memcached::RES_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -165,9 +110,9 @@ class Memcached extends Cache implements IMemcache {
|
|||
*/
|
||||
#[\Override]
|
||||
public function dec($key, $step = 1) {
|
||||
$result = self::$cache->decrement($this->getPrefix() . $key, $step);
|
||||
$result = $this->cache->decrement($this->getPrefix() . $key, $step);
|
||||
|
||||
if (self::$cache->getResultCode() !== \Memcached::RES_SUCCESS) {
|
||||
if ($this->cache->getResultCode() !== \Memcached::RES_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -180,6 +125,6 @@ class Memcached extends Cache implements IMemcache {
|
|||
}
|
||||
|
||||
private function isSuccess(): bool {
|
||||
return self::$cache->getResultCode() === \Memcached::RES_SUCCESS;
|
||||
return $this->cache->getResultCode() === \Memcached::RES_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
81
lib/private/Memcache/MemcachedFactory.php
Normal file
81
lib/private/Memcache/MemcachedFactory.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
namespace OC\Memcache;
|
||||
|
||||
use OC\SystemConfig;
|
||||
use OCP\HintException;
|
||||
use OCP\IConfig;
|
||||
use OCP\Server;
|
||||
|
||||
/**
|
||||
* Factory for \Memcached instance, to create a singleton
|
||||
*/
|
||||
class MemcachedFactory {
|
||||
private ?\Memcached $instance = null;
|
||||
|
||||
public function getInstance(): \Memcached {
|
||||
if ($this->instance === null) {
|
||||
$this->init();
|
||||
}
|
||||
return $this->instance;
|
||||
}
|
||||
|
||||
/** @psalm-assert \Memcached $this->instance */
|
||||
public function init(): void {
|
||||
$this->instance = new \Memcached();
|
||||
|
||||
$defaultOptions = [
|
||||
\Memcached::OPT_CONNECT_TIMEOUT => 50,
|
||||
\Memcached::OPT_RETRY_TIMEOUT => 50,
|
||||
\Memcached::OPT_SEND_TIMEOUT => 50,
|
||||
\Memcached::OPT_RECV_TIMEOUT => 50,
|
||||
\Memcached::OPT_POLL_TIMEOUT => 50,
|
||||
|
||||
// Enable compression
|
||||
\Memcached::OPT_COMPRESSION => true,
|
||||
|
||||
// Turn on consistent hashing
|
||||
\Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
|
||||
|
||||
// Enable Binary Protocol
|
||||
\Memcached::OPT_BINARY_PROTOCOL => true,
|
||||
];
|
||||
/**
|
||||
* By default enable igbinary serializer if available
|
||||
*
|
||||
* Psalm checks depend on if igbinary is installed or not with memcached
|
||||
* @psalm-suppress RedundantCondition
|
||||
* @psalm-suppress TypeDoesNotContainType
|
||||
*/
|
||||
if (\Memcached::HAVE_IGBINARY) {
|
||||
$defaultOptions[\Memcached::OPT_SERIALIZER]
|
||||
= \Memcached::SERIALIZER_IGBINARY;
|
||||
}
|
||||
$options = Server::get(IConfig::class)->getSystemValue('memcached_options', []);
|
||||
if (is_array($options)) {
|
||||
$options = $options + $defaultOptions;
|
||||
$this->instance->setOptions($options);
|
||||
} else {
|
||||
throw new HintException("Expected 'memcached_options' config to be an array, got $options");
|
||||
}
|
||||
|
||||
$servers = Server::get(SystemConfig::class)->getValue('memcached_servers');
|
||||
if (!$servers) {
|
||||
$server = Server::get(SystemConfig::class)->getValue('memcached_server');
|
||||
if ($server) {
|
||||
$servers = [$server];
|
||||
} else {
|
||||
$servers = [['localhost', 11211]];
|
||||
}
|
||||
}
|
||||
$this->instance->addServers($servers);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue