Skip to content

[FrameworkBundle] CacheWarmers are never executed in kernel.build_dir  #50357

@okhoshi

Description

@okhoshi

Description

While working on #50253, I realised that CacheWarmers are never executed in the kernel.build_dir (except in the case of the bug that I fixed in #50253).

For now, in a brand new Symfony project, only the compiled container is dumped in the build_dir. Looking at the documentation for kernel.build_dir (Build directory), it is described as

This directory can be used to separate read-only cache (i.e. the compiled container) from read-write cache (i.e. cache pools).

However, there's plenty of other ressources that could be considered as read-only IMHO: the router cache, Doctrine proxy classes, Symfony Config classes, translations, and probably many more.

Additionally, non-optional CacheWarmers are run during container init, in the cache_dir, which is erased if you run cache:clear command. Since the non-optional CacheWarmers are not executed in cache:clear command, because they run during container init, all the artefacts they produce are actually lost if you run cache:clear without an already existing container, which is happening on every composer install (some Doctrine CacheWarmers are concerned by this at least).

Besides, the mechanism of CacheWarmer seems a bit weird to me in some implementations of the interface. More specifically, the Symfony\Bundle\FrameworkBundle\Routing\Router that implements the WarmableInterface.

For reference, here's its implementation of the warmup function

    /**
     * @return string[] A list of classes to preload on PHP 7.4+
     */
    public function warmUp(string $cacheDir): array
    {
        $currentDir = $this->getOption('cache_dir');

        // force cache generation
        $this->setOption('cache_dir', $cacheDir);
        $this->getMatcher();
        $this->getGenerator();

        $this->setOption('cache_dir', $currentDir);

        return [
            $this->getOption('generator_class'),
            $this->getOption('matcher_class'),
        ];
    }

It seems to me that it's really error prone to have such back and forth with the cache_dir option. If someone changes the cache_dir setting of the Router, it won't be properly warmed up anymore, without any notice to the user.

So, to sum up a little bit, I can see three different issues, that may or may not be solve together.

  • build_dir is under utilised and many read-only warm ups could make use of it
  • Non-optional warmer artefacts are lost on initial cache:clear
  • WarmableInterface does not protect from misconfiguration.

I'm willing to contribute and propose a change to solve at least the first issue but would like to get some opinions on the best way to solve it beforehand :)

Example

s new --dir symfony_build_dir_problem
cd ./symfony_build_dir_problem
echo '<?php

namespace App;

use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;

class Kernel extends BaseKernel
{
    use MicroKernelTrait;

    public function getBuildDir(): string
    {
        return $this->getProjectDir()."/var/build/".$this->environment;
    }
}' > ./src/Kernel.php
composer install -q

Then see the content of var/build/dev and var/cache/dev.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy