Home » Php » php – Symfony2 command within an asynchronous subprocess

php – Symfony2 command within an asynchronous subprocess

Posted by: admin July 12, 2020 Leave a comment

Questions:

I am new on Symfony2 and I got blocked when trying to run an asynchronous command like this:

class MyCommand extends ContainerAwareCommand{

protected function configure()
{
    $this
        ->setName('my:command')
        ->setDescription('My command')
        ->addArgument(
            'country',
            InputArgument::REQUIRED,
            'Which country?'
        )
    ;
}

protected function execute(InputInterface $input, OutputInterface $output)
{

    $country = $input->getArgument('country');


    // Obtain the doctrine manager
    $dm = $this->getContainer()->get('doctrine_mongodb.odm.document_manager');

   $users = $dm->getRepository('MyBundle:User')
        ->findBy( array('country'=>$country));
}}

That works perfectly when I call it from my command line:

php app/console my:command uk

But it doesn’t work when I call it trowh a Symfony2 Process:

 $process = new Process("php ../app/console my:command $country");
 $process->start();

I get a database error: “[MongoWriteConcernException] 127.0.0.1:27017: not master

I think that means that the process is not getting my database configuration…

I just want to run an asynchronous process, is there other way to do it?

Maybe a way to call the Application Command that do not require the answer to keep going ?

Maybe I need to use injection?

PS: My current command is just a test, at the end it should be an ‘expensive’ operation…

How to&Answers:

Well, I found out what happened…

I use multiple environments: DEV, TEST and PROD.

And I also use differents servers.

So the DEV environment is my own machine with a simple mongodb configuration.
But the TEST environment is on other server with a replica set configuration…

Now the error get full sense: “[MongoWriteConcernException] 127.0.0.1:27017: not master”

To solve it, I’ve just added the environment parameter (–env=) to the process and everything worked like a charm:

$process = new Process("php ../app/console my:command $country --env=test");

Actually, to get the correct environment I use this:

$this->get('kernel')->getEnvironment();

Which let’s my code as follows:

$process = new Process("php ../app/console my:command $country --env=".$this->get('kernel')->getEnvironment());

Maybe is not a beautifull way to do it, but it works for me 🙂

Answer:

Disclamer: This might be a bit overkill for what you’re trying to do 🙂

I would choose an opposite way to do it: pthreads

First, quick examination of StackOverflow showed me a really nice example of using pthreads: Multi-threading is possible in php

Then, knowing that you could invoke your command from another command:

http://www.craftitonline.com/2011/06/calling-commands-within-commands-in-symfony2/

… lets you piece all the parts. It’s a bit complicated but it does the job.

Answer:

In case you want to execute your code completely async in Symfony2/3 there is AsyncServiceCallBundle for that.

You should just call it like this:

$this->get('krlove.async')->call('your_service_id', 'method_name', [$arg1, $arg2]);

Internally it uses this approach to run your code in background.