Skip to content

Commit

Permalink
feat(cache): CLI should not fail on missing memcache
Browse files Browse the repository at this point in the history
but fallback to NullCache. This can be the case if APCu is used without apc.enable_cli=1. APCu (and ArrayCache) 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 invalildate 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 or ArrayCache 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 cacking backend, causing a loop.

This commit re-adds the fallback without logging a warning. For mentioned reasons, it is okay to fallback to NullCache silently.

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>
  • Loading branch information
MichaIng committed Jun 26, 2024
1 parent 380a253 commit f280577
Showing 1 changed file with 22 additions and 6 deletions.
28 changes: 22 additions & 6 deletions lib/private/Memcache/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,30 @@ public function __construct(string $globalPrefix, LoggerInterface $logger, IProf
$missingCacheMessage = 'Memcache {class} not available for {use} cache';
$missingCacheHint = 'Is the matching PHP module installed and enabled?';
if (!class_exists($localCacheClass) || !$localCacheClass::isAvailable()) {
throw new \OCP\HintException(strtr($missingCacheMessage, [
'{class}' => $localCacheClass, '{use}' => 'local'
]), $missingCacheHint);
if (\OC::$CLI && !defined('PHPUNIT_RUN')) {
// CLI should not fail on missing memcache but fallback to NullCache
// This can be the case if APCu is used without apc.enable_cli=1.
// APCu however cannot be shared between PHP instances (CLI and web)
// and Nextcloud must not hard-depend on any cache.
$localCacheClass = self::NULL_CACHE;
} else {
throw new \OCP\HintException(strtr($missingCacheMessage, [
'{class}' => $localCacheClass, '{use}' => 'local'
]), $missingCacheHint);
}
}
if (!class_exists($distributedCacheClass) || !$distributedCacheClass::isAvailable()) {
throw new \OCP\HintException(strtr($missingCacheMessage, [
'{class}' => $distributedCacheClass, '{use}' => 'distributed'
]), $missingCacheHint);
if (\OC::$CLI && !defined('PHPUNIT_RUN')) {
// CLI should not fail on missing memcache but fallback to NullCache
// This can be the case if APCu is used without apc.enable_cli=1.
// APCu however cannot be shared between Nextcloud (PHP) instances
// and Nextcloud must not hard-depend on any cache.
$distributedCacheClass = self::NULL_CACHE;
} else {
throw new \OCP\HintException(strtr($missingCacheMessage, [
'{class}' => $distributedCacheClass, '{use}' => 'distributed'
]), $missingCacheHint);
}
}
if (!($lockingCacheClass && class_exists($lockingCacheClass) && $lockingCacheClass::isAvailable())) {
// don't fall back since the fallback might not be suitable for storing lock
Expand Down

0 comments on commit f280577

Please sign in to comment.