Команда запуска Symfony с контроллера на сервере

Я хочу очистить кеш от контроллера. Я определил команду как службу и вызываю ее.

clear_cache_command_service:
class: Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand
calls:
- [setContainer, ["@service_container"] ]

В моем контроллере у меня есть форма для выбора команды, и когда выбрана команда очистки кеша, она запускается:

    $clearCacheCommand = $this->container->get('clear_cache_command_service');
$clearCacheCommand->run(new ArrayInput(array()), new ConsoleOutput());

Это, однако, работает некоторое время, так как он также нагревает кэш (я на самом деле хочу, чтобы он также нагревался). Это также время ожидания, поэтому мне нужно set_time_limit это тоже.

Есть ли способ вернуть ответ в браузере и позволить команде выполнить и завершить работу на сервере? Я не хочу, чтобы клиент продолжал ждать его окончания.

3

Решение

Из-за того, как php работает — синхронно — это невозможно сделать «классическим» способом, в котором вам нужно ждать, пока команда завершится, чтобы завершить и отправить ответ. Решение здесь состоит в том, чтобы включить worker шаблон. Вы можете найти полезную информацию Вот. По сути, вам нужно добавить задачу «очистить кеш» в очередь и позволить другому процессу обрабатывать эту очередь, так что в вашем случае вызовите clear cache команда.

Распространенным решением, используемым в Symfony в таких случаях, является использование RabbitMQ, Есть много ресурсов об этом:

Использование в Symfony

RabbitMQBundle

Позвольте RabbitMQ сделать работу в вашем приложении Symfony2

4

Другие решения

Для запуска команды после ответа вы должны использовать слушатель на kernel.terminate событие. Цель этого события — выполнить задачи после того, как ответ уже был передан клиенту.

// send the headers and echo the content
$response->send();

// triggers the kernel.terminate event
$kernel->terminate($request, $response);

Пример слушателя

Kernel.terminate Событие документация

2

В качестве альтернативы RabbitMQ, о которой уже упоминалось, вы можете взглянуть на JMSJobBundle
http://jmsyst.com/bundles/JMSJobQueueBundle/master/installation

Пример кода, который я дал на этот мой старый ответ на похожий вопрос: Асинхронный вызов команды в Symfony2

1

Я нашел способ сделать это. Это немедленно вернет ответ и запустит команду в фоновом режиме. Не уверен, насколько это плохая практика.

/**
* @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);

}}
0
По вопросам рекламы [email protected]