dmb dmb - 2 months ago 19
PHP Question

Asynchronously calling a Command in Symfony2

I want to asynchronously call a Command from within a Controller in Symfony2.

So far i found the following solution:

$cmd = $this->get('kernel')->getRootDir().'/console '.(new MLCJobWorkerCommand)->getName().' '.$job->getId().' 2>&1 > /dev/null';
$process = new Process($cmd);

Is there a better way to accomplish this?


I need the Process to run in background and the Controller to return right after it started the former. I tried:

$cmd = $this->get('kernel')->getRootDir().'/console '
.(new MLCJobWorkerCommand)->getName()
.' '.$job->getId().' 2>&1 > /dev/null & echo \$!';
$process = new Process($cmd);
$params["processid"] = $process->getOutput();

but the Controller doesn't return a Response until the Process has finished.


I agree with Gerry that if you want to be "asynchronously" then you selected not the best way

I can recommend an alternative of RabbitMQ: JMSJobBundle

Where you can create a queue of you console commands something like:

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);

use JMS\JobQueueBundle\Entity\Job;

class CronJobHelper{

    public function createConsoleJob($consoleFunction, $params, $delayToRunInSeconds, $priority = Job::PRIORITY_DEFAULT, $queue = Job::DEFAULT_QUEUE){
            $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')); 

        return $job;