JessGabriel
JessGabriel

Reputation: 1072

Background task Symfony

What I want to do is to run a Symfony command separately from current request.

Goal: Generate a thumbnail from a PDF

Issue: I don't want to wait for the generation to be finished before sending response to the user.

    public function __invoke($myparam)
    {
        $command = sprintf(
            'php %s/bin/console ps:media:generate-thumbnail %s %s &',
            $this->kernel->getProjectDir(),
            'destinationPath',
            'sourcePath'
        );

        exec($command);
    }

Issue is, server still wait for the command to be done before sending response

Upvotes: 1

Views: 655

Answers (3)

murtho
murtho

Reputation: 1031

You could use Cocur Background Progress library to manage background progresses

$command = sprintf(
     'exec php %s/bin/console ps:media:generate-thumbnail %s %s &',
     $this->kernel->getProjectDir(),
     'destinationPath',
     'sourcePath'
);

$process = new BackgroundProcess($command);

$process->run();

Upvotes: 1

myxaxa
myxaxa

Reputation: 1381

so, exec function waiting for stdio stream, so you just need to reassign it somewhere else, /dev/null is cool ^_^

public function __invoke($myparam)
    {
        $command = sprintf(
            'php %s/bin/console ps:media:generate-thumbnail %s %s > /dev/null &',
            $this->kernel->getProjectDir(),
            'destinationPath',
            'sourcePath'
        );

        exec($command);
    }

Upvotes: 2

Dimitris
Dimitris

Reputation: 452

If you are using PHP FPM, a nice way to handle such requirements on Symfony is to use a listener on the kernel.terminate event. From the documentation:

This event is dispatched after the response has been sent (after the execution of the handle() method). It's useful to perform slow or complex tasks that don't need to be completed to send the response (e.g. sending emails).

Apart from writing a listener, you also have to add the snippet bellow to your front controller, after the $response->send() call

$response->send(); 
$kernel->terminate($request, $response);

You can find more on the symfony documentation

https://symfony.com/doc/current/components/http_kernel.html#component-http-kernel-kernel-terminate

Upvotes: 1

Related Questions