Skip to content

Commit 033c911

Browse files
committed
feat(cache): CLI should not fail if APCu is not available
but fallback to NullCache. This can be the case if APCu is used without apc.enable_cli=1. APCu however runs within the PHP instance and hence cannot be shared between CLI and web or used as distributed cache. The CLI call can hence only create or invalidate entries for itself. For short-living CLI calls, this is theoretically a downsides regarding performance and resource usage, and Nextcloud must not have any issues using the dummy NullCache instead of an isolated freshly created and destroyed APCu instance. This partly reverts #25770. The fallback was removed, because CLI calls started to hang after #25440. The reason however was not that a cache is generally required for CLI calls, but because the previously logged warning invoked the user backend, which invoked again the caching backend, causing a loop. This commit re-adds the fallback without logging a warning, and for APCu only. For mentioned reasons, it is okay to fallback to NullCache silently. If Redis or memcached are configured but not available, then the web UI would fail as well, and it makes sense to abort and inform CLI calls as well then. The motivation is to make apc.enable_cli=1 optional, and that hence the documentation about it can be removed. We should not enforce admins to enable APCu for CLI calls, which is reasonably disabled by default. This also reduces requirements for hosting providers to support Nextcloud. Signed-off-by: MichaIng <micha@dietpi.com>
1 parent 40fb16b commit 033c911

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

lib/private/Memcache/Factory.php

+20-6
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,28 @@ public function __construct(string $globalPrefix, LoggerInterface $logger, IProf
6464
$missingCacheMessage = 'Memcache {class} not available for {use} cache';
6565
$missingCacheHint = 'Is the matching PHP module installed and enabled?';
6666
if (!class_exists($localCacheClass) || !$localCacheClass::isAvailable()) {
67-
throw new \OCP\HintException(strtr($missingCacheMessage, [
68-
'{class}' => $localCacheClass, '{use}' => 'local'
69-
]), $missingCacheHint);
67+
if (\OC::$CLI && !defined('PHPUNIT_RUN') && $localCacheClass === APCu::class) {
68+
// CLI should not fail if APCu is not available but fallback to NullCache.
69+
// This can be the case if APCu is used without apc.enable_cli=1.
70+
// APCu however cannot be shared between PHP instances (CLI and web) anyway.
71+
$localCacheClass = self::NULL_CACHE;
72+
} else {
73+
throw new \OCP\HintException(strtr($missingCacheMessage, [
74+
'{class}' => $localCacheClass, '{use}' => 'local'
75+
]), $missingCacheHint);
76+
}
7077
}
7178
if (!class_exists($distributedCacheClass) || !$distributedCacheClass::isAvailable()) {
72-
throw new \OCP\HintException(strtr($missingCacheMessage, [
73-
'{class}' => $distributedCacheClass, '{use}' => 'distributed'
74-
]), $missingCacheHint);
79+
if (\OC::$CLI && !defined('PHPUNIT_RUN') && $distributedCacheClass === APCu::class) {
80+
// CLI should not fail if APCu is not available but fallback to NullCache.
81+
// This can be the case if APCu is used without apc.enable_cli=1.
82+
// APCu however cannot be shared between Nextcloud (PHP) instances anyway.
83+
$distributedCacheClass = self::NULL_CACHE;
84+
} else {
85+
throw new \OCP\HintException(strtr($missingCacheMessage, [
86+
'{class}' => $distributedCacheClass, '{use}' => 'distributed'
87+
]), $missingCacheHint);
88+
}
7589
}
7690
if (!($lockingCacheClass && class_exists($lockingCacheClass) && $lockingCacheClass::isAvailable())) {
7791
// don't fall back since the fallback might not be suitable for storing lock

0 commit comments

Comments
 (0)