我想从控制器中清除缓存。我已将该命令定义为服务并调用它。
clear_cache_command_service:
class: Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand
calls:
- [setContainer, ["@service_container"] ]
在我的控制器中,我有一个表单来选择一个命令,当选择了cache-clearing命令时,它会运行:
$clearCacheCommand = $this->container->get('clear_cache_command_service');
$clearCacheCommand->run(new ArrayInput(array()), new ConsoleOutput());
然而这会运行一段时间,因为它也会使缓存变暖(我实际上也希望它也能加热它)。它也超时,所以我也需要set_time_limit
它。
有没有办法在浏览器中返回响应并让命令在服务器上运行并完成?我不希望客户端等待它完成。
答案 0 :(得分:4)
由于worker
如何工作 - 同步 - 不可能以“经典”的方式进行,您需要等待命令完成终止并发送响应。这里的解决方案是合并clear cache
模式。您可以找到一些有用的信息here。基本上你需要将“clear cache”任务添加到队列中,让其他进程处理这个队列,所以在你的情况下调用counter
命令。
在这种情况下,symfony中使用的常见解决方案是使用RabbitMQ,有很多相关资源:
答案 1 :(得分:2)
要在响应后运行命令,必须在 kernel.terminate 事件上使用侦听器。此事件的目的是在响应已经提供给客户端后执行任务。
// send the headers and echo the content
$response->send();
// triggers the kernel.terminate event
$kernel->terminate($request, $response);
答案 2 :(得分:1)
作为已经提及的RabbitMQ的替代方案,您可以查看JMSJobBundle http://jmsyst.com/bundles/JMSJobQueueBundle/master/installation
我在这个问题上给出了一些代码示例:Asynchronously calling a Command in Symfony2
答案 3 :(得分:0)
我找到了办法。这将立即返回响应并使命令在后台运行。不确定这是多么糟糕的做法。
/**
* @Service("background_command_runner")
*/
class BackgroundCommandRunner
{
private $kernelDir;
/**
* @InjectParams({
* "kernelDir" = @Inject("%kernel.root_dir%")
* })
*/
public function __construct($kernelDir)
{
$this->kernelDir = $kernelDir;
}
public function run($cmd)
{
$path = $this->kernelDir . '\console ';
$fullCmd = "php " . $path . $cmd;
if (substr(php_uname(), 0, 7) == "Windows") {
pclose(popen("start /B " . $fullCmd, "r"));
} else {
exec($fullCmd . " >> logs/theme.log &");
}
}
public function clearCache($env = "dev", $warm = true)
{
$toWarm = $warm ? "" : " --no-warmup";
$cmd = "cache:clear " . "--env=" . $env . $toWarm;
$this->run($cmd);
}
}