symfony/process - Process silently not starting
Asked Answered
S

2

5

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 launching a symfony2 command, but the workaround with exec is not working for me.

Does somebody have a clue?

Thanks, regards, jojo

Samal answered 22/12, 2014 at 16:14 Comment(1)
as for the downvote: nevermind, but as this has been my first question here I would appreciate a short feedback on what to improve. Thanks :)Samal
K
12

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.

Kranz answered 22/12, 2014 at 19:14 Comment(4)
Thanks for your help. Yes, starting the process asynchronously is intended and I guess you are right that the fpm is just killing the related process when the request is finished. I realy would like to understand why it works exactly 1 time before this behaviour occurs. Anyway, implementing the whole thing through a message-queue is a solution indeed, so thank you.Samal
I dont get why its called "asynchronously". For me "process asynchronously" means "run and forget". Both Process::run() and Process:start() block current request which results in "max execution time exceeded" error. Trying to understand the whole point of Symfony Process lib, it's bloated and useless. I never had any problems with simple exec()Saphra
Process::start() doesn't block. wait() blocks, which is handy if you need to wait for the result. One on the things that Process component does well is dealing with differences between various platform. Good luck making your exec() work with both Linux and Windows!Kranz
I'm running Laravel Homestead vagrant box on Win. It's a unix box. Both Process::run() and Process:start() block without wait(). exec() works just great.Saphra
H
0

Just one update for 2020 .... i was getting an silent error, and did this to debug

$process = new Process($command);
$process->run();
print_r($process->getErrorOutput());
Huntingdon answered 2/7, 2020 at 20:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.