Vladimir Cvetic
Vladimir Cvetic

Reputation: 842

Boostraping symfony 2 for pthread from command

I'm trying to start threads from symfony 2 command.

protected function execute(InputInterface $input, OutputInterface $output)
{
    $parser = $this->getContainer()->get('app.article.parser');
    $providers = $parser->getProviders();
    foreach ($providers as $name=>$provider) 
    {
        $parseThread = new ParseThread($parser, $name);
        $parseThread->start();
    }
}

ParseThread class:

class ParseThread extends \Thread 
{

private $parser;
private $providerName;

function __construct (Parser $parser, $providerName) 
{
    $this->parser       = $parser;
    $this->providerName = $providerName;
}

public function run () 
{
    $this->parser->parse($this->providerName);
}

}

$this->parser->parse(...) should, as I understand it be started in new thread. Inside parse method, based on string $providerName, bunch of classes are initialized.

Problem here is that new thread does not have Symfony 2 bootstrapped and thus has no composer autoloading - so my classes are not being loaded.

Is there any sensible way to bootstrap Symfony 2 in each thread, thus allowing for autoloading and all other things to work normally ?

Upvotes: 2

Views: 1067

Answers (2)

Vladimir Cvetic
Vladimir Cvetic

Reputation: 842

I ended up adding this to run method:

    $loader = require_once $kernel_root_dir.'/bootstrap.php.cache';
    require_once $kernel_root_dir.'/AppKernel.php';
    $kernel = new \AppKernel($env, true);

Adding only autoloaded did in fact load all classes, but produced a lot of other errors. Above code will bootstrap entire symfony 2, which will probably produce a bit larger footprint in each thread.

Upvotes: 1

Igor Pantović
Igor Pantović

Reputation: 9246

PThreads doesn't inherit autoloading. This, however, shouldn't be a big deal. You can just do:

<?php

class ParseThread extends \Thread 
{

    private $parser;
    private $providerName;

    function __construct (Parser $parser, $providerName) 
    {
        $this->parser       = $parser;
        $this->providerName = $providerName;
    }

    public function run () 
    {
        require_once 'location/to/vendor/autoload.php';
        $this->parser->parse($this->providerName);
    }

}

Upvotes: 3

Related Questions