我想从Symfony2中的Controller中异步调用命令。
到目前为止,我找到了以下解决方案:
$cmd = $this->get('kernel')->getRootDir().'/console '.(new MLCJobWorkerCommand)->getName().' '.$job->getId().' 2>&1 > /dev/null';
$process = new Process($cmd);
$process->start();
有没有更好的方法来实现这一目标?
修改
我需要Process在后台运行,Controller需要在启动前者后立即返回。我试过了:
$cmd = $this->get('kernel')->getRootDir().'/console '
.(new MLCJobWorkerCommand)->getName()
.' '.$job->getId().' 2>&1 > /dev/null & echo \$!';
$process = new Process($cmd);
$process->mustRun();
$params["processid"] = $process->getOutput();
但是在Process完成之前,Controller不会返回响应。
答案 0 :(得分:5)
我同意Gerry的意见,如果你想成为"异步"然后你选择的不是最好的方式
我可以推荐RabbitMQ的另一种选择:JMSJobBundle
http://jmsyst.com/bundles/JMSJobQueueBundle/master/installation
您可以在其中创建控制台命令的队列,例如:
class HomeController ... {
// inject service here
private $cronJobHelper;
// inject EM here
private $em;
public function indexAction() {
$job = $this->cronJobHelper->createConsoleJob('myapp:my-command-name', $event->getId(), 10);
$this->em->persist($job);
$this->em->persist($job);
$this->em->flush();
}
}
use JMS\JobQueueBundle\Entity\Job;
class CronJobHelper{
public function createConsoleJob($consoleFunction, $params, $delayToRunInSeconds, $priority = Job::PRIORITY_DEFAULT, $queue = Job::DEFAULT_QUEUE){
if(!is_array($params)){
$params = [$params];
}
$job = new Job($consoleFunction, $params, 1, $queue, $priority);
$date = $job->getExecuteAfter();
$date = new \DateTime('now');
$date->setTimezone(new \DateTimeZone('UTC')); //just in case
$date->add(new \DateInterval('PT'.$delayToRunInSeconds.'S'));
$job->setExecuteAfter($date);
return $job;
}
}
答案 1 :(得分:0)
Checkout AsyncServiceCallBundle,它允许您使用this方法完全异步调用服务的方法。负责当前请求处理的进程不等待其子进程完成。
你需要的一切就是这样称呼它:
$pid = $this->get('krlove.async')->call('service_id', 'method', [$argument1, $argument2]);