[Cache] Cannot warm or clear APCu cache from CLI with apc.enable_cli
set to false
#54066
-
Symfony version(s) affected
DescriptionIf This means that CLI can't be used to warm APCu cache even when that is actually supported. How to reproduce<?php
use Symfony\Component\Cache\Adapter\ApcuAdapter;
use Symfony\Component\Cache\Adapter\ChainAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
require_once __DIR__ . '/vendor/autoload.php';
$cacheNamespace = 'MyCacheExample';
$cacheLifetime = 300;
$isCli = 'cli' === \PHP_SAPI && !ini_get('apc.enable_cli');
$adapters = [
new FilesystemAdapter($cacheNamespace, $cacheLifetime, __DIR__ . '/' . $cacheNamespace)
];
if (ApcuAdapter::isSupported()) {
$apcuAdapter = new ApcuAdapter($cacheNamespace, $cacheLifetime);
// Note the order doesn't REALLY matter for this demonstration, but we should still ideally have the cache we *know* we can read from first.
if ($isCli) {
// Add it second so we're pulling from the filesystem, since APCu isn't available for reading
$adapters[] = $apcuAdapter;
} else {
// Add it first so we're pulling from memory where possible
array_unshift($adapters, $apcuAdapter);
}
}
$cache = new ChainAdapter($adapters, $cacheLifetime);
if ($isCli) {
echo "CLI" . PHP_EOL;
$cache->clear();
} else {
echo "Not CLI" . PHP_EOL;
}
$cache->get('my-cache-item', function () use ($isCli) {
$value = $isCli ? 'CLI value' : 'not-CLI value';
return $value . time();
});
$cache->commit();
echo $cache->getItem('my-cache-item')->get(); I think the order you need to run this is:
The first run will set the cache in APCu. This should get you into a state where the CLI output is always different from the non-CLI output (at least until the APCu cache times out, at which point you might get lucky and they'll sync up) Possible SolutionIdeally, that If we want to be really careful, then if Additional ContextNote that in #25080 the suggestion to check |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 1 reply
-
(I think I've got that code example right....) |
Beta Was this translation helpful? Give feedback.
-
Hmm I had assumed that this I've updated the code example to include a timestamp in the value so it's clearer when there's a hit vs a miss. |
Beta Was this translation helpful? Give feedback.
-
More on this - looks like even if I enable So... maybe that's just explicitly not supported by APCu? |
Beta Was this translation helpful? Give feedback.
-
APCu cache is not the kind of cache you may be used to everywhere else. This is a shared cache. It works for PHP-FPM (child processes accessing cache from parent) and mod_php. While it works for CLI too it does not make any sense to use it, since each CLI process dies at the end of execution and thus loses all cached information. CLI processes do not have access to cache created from web requests (php-fpm, mod_php), this is why there are community made "monitoring scripts" for APCu. I used such a script too: https://github.com/nvthaovn/APCu-Gui-Admin I could clear the cache from this admin panel or by restarting the php-fpm service. The latter was just a consequence if we had to restart the service for other reasons though. More on APCu and shared cache: https://stackoverflow.com/questions/34533695/is-the-new-apcu-apc-user-cache-shared-between-processes In conclusion if you want to warmup cache from the CLI for the web too, I would suggest you choose Redis or perhaps memcached. If you insist on using APCu and the CLI, there are possible "hacky" solutions I would personally come up with. You can create a special route which is secured and visited from the CLI, this will actually be a web request (but triggered from the CLI) which warms up your cache. Feel free to correct me, if I'm wrong, but this is my experience with APCu and CLI. |
Beta Was this translation helpful? Give feedback.
-
APCu shared memory is process-specific. This means it's not possible to warmup or reset it from the CLI and have this impact another (non-CLI) process. That explains the chain behavior BTW: warming up can only be done with a persistent storage (the fs-adapter). |
Beta Was this translation helpful? Give feedback.
APCu shared memory is process-specific. This means it's not possible to warmup or reset it from the CLI and have this impact another (non-CLI) process. That explains the chain behavior BTW: warming up can only be done with a persistent storage (the fs-adapter).
And clearing must be done from within non-CLI (most likely by restarting the webserver).
You need to use another backend if this behavior doesn't fit your need.