为什么我的 Symfony 2 缓存加热器被多次调用


Why is my Symfony 2 cache warmer called multiple times?

我在Symfony 2应用程序中的一个捆绑包有一个自定义的缓存加热器。

从控制台和开发模式下运行时,它会向 stdout 写入通知,告知它已被调用。

有时,并非总是如此,它被多次调用为单个控制台缓存:clear 命令,如写入 stdout 的多个通知所证明的那样。

有人可以解释为什么会发生这种情况吗?正常吗?是否所有缓存预热器都调用了多次?

环境:

  • 乌班图 14.04.3
  • 菲律宾比索 7.0.2-4
  • Symfony 2.7.9

------ 编辑 21-Feb-2016 08:36 -------

由于各种原因(大小、保密协议等),按实际来源发布是不切实际的。因此,我创建了一个带有缓存加热器的小捆绑包,它在调用时只回显其类名。

正如您在下面的输出中看到的,它被调用了两次。

//
// The cache warmer.
//
namespace SoBundle'Listener;
use Symfony'Component'HttpKernel'CacheWarmer'CacheWarmerInterface;
class CacheWarmer implements CacheWarmerInterface
{
    public function isOptional()
    {
        return false;
    }
    public function warmUp( $cacheDir )
    {
        echo __CLASS__ . '()' . PHP_EOL;
    }
}
#
# The service definition.
#
services:
    so.cache_warmer:
        class: SoBundle'Listener'CacheWarmer
        tags:
            - { name: kernel.cache_warmer }
#
# Clearing the cache...
#
$ console cache:clear
Clearing the cache for the dev environment with debug true
SoBundle'Listener'CacheWarmer()
SoBundle'Listener'CacheWarmer()
单次

执行 console cache:clear 可能会触发 0 到 3 次缓存预热,具体取决于以下因素:

  1. 缓存的当前状态,
  2. 可选参数(例如 --no-warmup--no-optional-warmers),
  3. 缓存预热器是否可选(根据isOptional()方法)。

一个小介绍:Symfony使用一个名为cache_warmer的服务,该服务映射到Symfony'Component'HttpKernel'CacheWarmer'CacheWarmerAggregate类。它用于聚合所有标记为kernel.cache_warmer的注册缓存预热服务,并提供执行它们的便捷方法。

在调用期间显式启动缓存预热的方法有 2 console cache:clear

  1. Symfony'Component'HttpKernel'Kernel::initializeContainer() - 每次内核初始化时执行,无论是在控制台模式下还是在 Web 模式下。如果您没有热缓存,它会触发非可选的缓存预热器。
  2. Symfony'Bundle'FrameworkBundle'Command'CacheClearCommand::warmup() - 由console cache:clear命令执行。它会根据使用的选项触发所有或仅可选的加热器。但更重要的是,它实际上通过$this->getTempKernel()创建了一个临时内核,该内核也会在初始化期间触发非可选的缓存预热器(如上所述)。

这样可以对每个缓存预热服务进行 0-3 次调用。基于 Symfony v2.8.3。

附言出于好奇,只花了2个小时就挖掘了Symfony代码;)