Jojo Jojo - 6 months ago 57
PHP Question

symfony/process - Process silently not starting

In a fresh symfony2-project (installation as described here), I would like to start a console-process as part of a request. The app runs on a "standard" ubuntu 14.04 box with nginx + php-fpm.

Consider this controller-code:

<?php
namespace AppBundle\Controller;


use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Process\Process;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class CommandController extends Controller
{
/**
* @Route("/command")
* @return JsonResponse
*/
public function commandAction ()
{
$rootDir = $this->get('kernel')->getRootDir();
$env = $this->get('kernel')->getEnvironment();
$commandline = $rootDir . '/console --env=' . $env . ' acme:hello --who jojo'
$process = new Process($commandline);
$process->start();
return new JsonResponse(array('command' => $commandline));
}
}


When I issue a request to /command, I get my expected result and the process starts, e.g. I see it with htop and the like.
When I issue this request again, I get my expected result, but the process to be started does not show up anywhere. No errors, no nothing.

Restarting the php5-fpm service enables me to start one process through a request again, so basically I need to restart the whole php-service after each request. So this maybe is no programming-issue. But I don't know yet, honestly.
The problem was described on stackoverflow before, Symfony2 - process lunching a symfony2 command, but the workaround with exec is not working for me.

Does somebody have a clue?

Thanks, regards,
jojo

Answer

Your process most likely dies before it manages to finish its work. It's because PHP kills it after the response is returned back to the client and connection is closed.

Process::start() is used to start a process asynchronously. You need to either wait() for it to finish or check if it has finished yet with isRunning():

$process->start();

$process->wait(function ($type, $buffer) {
    // do sth while you wait
});

Alternatively, use Process::run() instead of Process:start().

Use message queues if you want to process something in background.