diff --git a/lib/private/memcache/factory.php b/lib/private/memcache/factory.php index 5bb7e42c80..fe82558e73 100644 --- a/lib/private/memcache/factory.php +++ b/lib/private/memcache/factory.php @@ -29,6 +29,7 @@ namespace OC\Memcache; use \OCP\ICacheFactory; +use \OCP\ILogger; class Factory implements ICacheFactory { const NULL_CACHE = '\\OC\\Memcache\\NullCache'; @@ -38,6 +39,11 @@ class Factory implements ICacheFactory { */ private $globalPrefix; + /** + * @var ILogger $logger + */ + private $logger; + /** * @var string $localCacheClass */ @@ -55,13 +61,15 @@ class Factory implements ICacheFactory { /** * @param string $globalPrefix + * @param ILogger $logger * @param string|null $localCacheClass * @param string|null $distributedCacheClass * @param string|null $lockingCacheClass */ - public function __construct($globalPrefix, + public function __construct($globalPrefix, ILogger $logger, $localCacheClass = null, $distributedCacheClass = null, $lockingCacheClass = null) { + $this->logger = $logger; $this->globalPrefix = $globalPrefix; if (!$localCacheClass) { @@ -71,22 +79,43 @@ class Factory implements ICacheFactory { $distributedCacheClass = $localCacheClass; } + $missingCacheMessage = 'Memcache {class} not available for {use} cache'; + $missingCacheHint = 'Is the matching PHP module installed and enabled?'; if (!$localCacheClass::isAvailable()) { - throw new \OC\HintException( - 'Missing memcache class ' . $localCacheClass . ' for local cache', - 'Is the matching PHP module installed and enabled ?' - ); + if (\OC::$CLI && !defined('PHPUNIT_RUN')) { + // CLI should not hard-fail on broken memcache + $this->logger->info($missingCacheMessage, [ + 'class' => $localCacheClass, + 'use' => 'local', + 'app' => 'cli' + ]); + $localCacheClass = self::NULL_CACHE; + } else { + throw new \OC\HintException(strtr($missingCacheMessage, [ + '{class}' => $localCacheClass, '{use}' => 'local' + ]), $missingCacheHint); + } } if (!$distributedCacheClass::isAvailable()) { - throw new \OC\HintException( - 'Missing memcache class ' . $distributedCacheClass . ' for distributed cache', - 'Is the matching PHP module installed and enabled ?' - ); + if (\OC::$CLI && !defined('PHPUNIT_RUN')) { + // CLI should not hard-fail on broken memcache + $this->logger->info($missingCacheMessage, [ + 'class' => $distributedCacheClass, + 'use' => 'distributed', + 'app' => 'cli' + ]); + $distributedCacheClass = self::NULL_CACHE; + } else { + throw new \OC\HintException(strtr($missingCacheMessage, [ + '{class}' => $distributedCacheClass, '{use}' => 'distributed' + ]), $missingCacheHint); + } } if (!($lockingCacheClass && $lockingCacheClass::isAvailable())) { // dont fallback since the fallback might not be suitable for storing lock - $lockingCacheClass = '\OC\Memcache\NullCache'; + $lockingCacheClass = self::NULL_CACHE; } + $this->localCacheClass = $localCacheClass; $this->distributedCacheClass = $distributedCacheClass; $this->lockingCacheClass = $lockingCacheClass; diff --git a/lib/private/server.php b/lib/private/server.php index 84141fe28c..53949b53df 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -50,7 +50,6 @@ use OC\Http\Client\ClientService; use OC\Lock\MemcacheLockingProvider; use OC\Lock\NoopLockingProvider; use OC\Mail\Mailer; -use OC\Memcache\ArrayCache; use OC\Memcache\NullCache; use OC\Security\CertificateManager; use OC\Security\Crypto; @@ -234,17 +233,17 @@ class Server extends SimpleContainer implements IServerContainer { $instanceId = \OC_Util::getInstanceId(); $path = \OC::$SERVERROOT; $prefix = md5($instanceId.'-'.$version.'-'.$path); - return new \OC\Memcache\Factory($prefix, + return new \OC\Memcache\Factory($prefix, $c->getLogger(), $config->getSystemValue('memcache.local', null), $config->getSystemValue('memcache.distributed', null), $config->getSystemValue('memcache.locking', null) ); } - return new \OC\Memcache\Factory('', - new ArrayCache(), - new ArrayCache(), - new ArrayCache() + return new \OC\Memcache\Factory('', $c->getLogger(), + '\\OC\\Memcache\\ArrayCache', + '\\OC\\Memcache\\ArrayCache', + '\\OC\\Memcache\\ArrayCache' ); }); $this->registerService('ActivityManager', function (Server $c) { diff --git a/tests/lib/memcache/factory.php b/tests/lib/memcache/factory.php index c25e5937c1..33a27a4211 100644 --- a/tests/lib/memcache/factory.php +++ b/tests/lib/memcache/factory.php @@ -114,7 +114,8 @@ class Test_Factory extends \Test\TestCase { */ public function testCacheAvailability($localCache, $distributedCache, $lockingCache, $expectedLocalCache, $expectedDistributedCache, $expectedLockingCache) { - $factory = new \OC\Memcache\Factory('abc', $localCache, $distributedCache, $lockingCache); + $logger = $this->getMockBuilder('\OCP\ILogger')->getMock(); + $factory = new \OC\Memcache\Factory('abc', $logger, $localCache, $distributedCache, $lockingCache); $this->assertTrue(is_a($factory->createLocal(), $expectedLocalCache)); $this->assertTrue(is_a($factory->createDistributed(), $expectedDistributedCache)); $this->assertTrue(is_a($factory->createLocking(), $expectedLockingCache)); @@ -125,6 +126,7 @@ class Test_Factory extends \Test\TestCase { * @expectedException \OC\HintException */ public function testCacheNotAvailableException($localCache, $distributedCache) { - new \OC\Memcache\Factory('abc', $localCache, $distributedCache); + $logger = $this->getMockBuilder('\OCP\ILogger')->getMock(); + new \OC\Memcache\Factory('abc', $logger, $localCache, $distributedCache); } }