在Symfony2中异步调用命令

时间:2015-04-13 08:39:34

标签: php symfony

我想从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不会返回响应。

2 个答案:

答案 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]);