So controlling my cache from command line or modifying env.php
doesn't seem to work. Going into admin showed them all as disabled. Enabling them however within admin worked fine and shows all enabled from command line, env.php and within admin. Modifying them on command line however does nothing but modify env.php and make you think its enabled. What is going on!?
When i disable my opcache the issue stops happening and breaks when I enable. I have to flush my opcache everytime for the changes in the cache to become active but only when configuring cache via CLI or direct changes to env.php
. Opcache seems to be caching these configs now it seems?
For now I have blacklisted env.php
from opcache however am nervous that more issues may arise here as have never had to do this before.
Steps I have taken
bin/magento cache:status
shows all caches set to 1.- Checked
env.php
, this has updated fine - Reset permissions as per dev docs
- I can't find any instances of
cacheable="false"
within theme or modules - No errors show in logs
- Checked redis which seems to be working however hard to debug the database being being used.
- Disabled all custom modules.
- Wanted to disable theme however new bug in 2.2.4 is stopping this (have renamed to bak majority of folders within theme for now)
- Restored a database backup
- …Asked a question on here.
- Stuck a bounty on it.
Cache:enable process
I have tried tracing what is actually going on when i run this command and so far I can see that the following happens:
Defined in Magento\Backend\Console\Command
which extends AbstractCacheSetCommand
protected function configure()
{
$this->setName('cache:enable');
$this->setDescription('Enables cache type(s)');
parent::configure();
}
This then sets enabled the applicable cache types:
$changedTypes = $this->cacheManager->setEnabled($types, $isEnable);
A few more steps through classes shows this command does the following:
public function setEnabled(array $types, $isEnabled)
{
$changedStatusTypes = [];
$isUpdated = false;
foreach ($types as $type) {
if ($this->cacheState->isEnabled($type) === $isEnabled) { // no need to poke it, if is not going to change
continue;
}
$this->cacheState->setEnabled($type, $isEnabled);
$isUpdated = true;
$changedStatusTypes[] = $type;
}
if ($isUpdated) {
$this->cacheState->persist();
}
return $changedStatusTypes;
}
However the following line leads me too and interface and am unable to determine the exact contents of that method:
$this->cacheState->setEnabled($type, $isEnabled);
This then runs below code:
public function setEnabled($cacheType, $isEnabled)
{
$this->load();
$this->statuses[$cacheType] = (int)$isEnabled;
}
And as Marius points out the persist function is what actually updates env.php
.
public function persist()
{
$this->load();
$this->writer->saveConfig([ConfigFilePool::APP_ENV => [self::CACHE_KEY => $this->statuses]]);
}
This all seems to work correctly however will leave here as may help any future debugging. However in my situation env.php
updates fine and this seems to be where cache configs should be read from, however i have discovered they seem to be cached in opache for some reason.
Best Answer
Picking up from where you got stuck....
the implementation of the interface
StateInterface
isMagento\Framework\App\Cache\State
.method
setEnabled
looks like this:This is in a default install. If you have other custom modules that use a different implementation for the Cache states interface maybe you should look in there.
Moving on to the
persist
method...It should be in the same class
this is the actual method that should write in
env.php
.You can easily test if when running the command you reach this method.
(use a simple var_dump, die for test purposes).
If you do not reach this code it means you are using a different implementation for this interface.
And you can check this easily by adding
(or use xdebug and adding a breakpoint)
right before
$this->cacheState->setEnabled($type, $isEnabled);