-
-
Couldn't load subscription status.
- Fork 4.6k
Description
How to use GitHub
- Please use the 👍 reaction to show that you are interested into the same feature.
- Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
- Subscribe to receive notifications on status change and new comments.
Is your feature request related to a problem? Please describe.
After #25440, Nextcloud requires the configured memory cache (config.php > memcache.local) to be available as well for CLI calls. By default PHP APCu is disabled for CLI calls, which already did produce a log entry in the past and it was always recommended to enable it (apc.enable_cli=1) to avoid potential issues with some background jobs. It is however not optimal to initiate a caching instance for a CLI command, which usually does not repeatedly read the same resource, so that building the cache slows down the whole call more than the benefit of having involved resources cached. Also this can lead to a significant increase of memory usage, when CLI calls stack, each with an own cache instance. This matter has been further discussed in #25770.
Describe the solution you'd like
In case of CLI falls, if the configured memory cache is not available (apc.enable_cli=0 and alike), fallback to NullCache, as if no cache was configured (memcache.local unset or none).
Describe alternatives you've considered
An alternative would be to use NullCache in the first place on all CLI calls, ignoring the memcache.local value. But it won't have any benefit as long as the backend itself (PHP module or server) has been initialised or is running anyway.
Additional context
For me, the related code block already looks like it does what I suggest, but obviously it does not, as otherwise the loop, worked around with #25770 wouldn't exist. Here is how I understand the code (obviously wrong), and hopefully someone can point me to the thing I misinterpret:
- https://github.com/nextcloud/server/blob/0c5adad/lib/private/Memcache/Factory.php#L40
The cache factory constructor creates a global variable for the "NullCache".
public const NULL_CACHE = NullCache::class;
- https://github.com/nextcloud/server/blob/0c5adad/lib/private/Memcache/Factory.php#L74-L84
This NullCache is applied for local and distributed cache, as long as no other one has been configured. - https://github.com/nextcloud/server/blob/0c5adad/lib/private/Memcache/NullCache.php#L30
This "NullCache" is basically a dummy cache which returns always true on
class NullCache extends Cache implements \OCP\IMemcache {
isAvailable()but returns null/false on everyget()/hasKey(). - https://github.com/nextcloud/server/blob/0c5adad/lib/private/Memcache/Factory.php#L88-L96
If an invalid cache has been configured
$localCacheClass = self::NULL_CACHE;
!class_exists($localCacheClass)or it is not available!$localCacheClass::isAvailable()and it is a CLI call(\OC::$CLI && !defined('PHPUNIT_RUN')), assign theNULL_CACHEvariable, and hence the "NullCache" as local and distributed caching backend respectively. - So when APCu is configured (a valid cache) but not available in a CLI call (
apc.enable_cli=0), the NullCache backend will be used instead. As it is a valid caching backend (though a dummy) as well and itsisAvailable()always returns true, the same condition can never be met and hence the loop described in Don't allow executing cli if cache backend is unavailable #25770 should not exist. - Where am I wrong?