简体   繁体   中英

Doctrine Entity Manager with PThreads and Symfony 4

I'm using php-zts to perform parallel data processing, using symfony 4 and PThreads

I'm great at running multiple threads, but I'm facing a problem, I need each of the threads to be able to work with doctrine

I need to make sure that each thread is able to work with doctrine

I tried to transfer a container instance directly, but it won't work because it can't be sterilized

/console_comand.php

private function gettingStatistics(){
        $pool = new \Pool(4, Autoloader::class, ["vendor/autoload.php"]);
        $store = new \Threaded();
        $class = new Meta();
        $pool->submit(new Task($class,$store));
        $pool->collect();
        $pool->shutdown();
        $listQuotes = array();
        foreach ($store as $obj){
            foreach ($obj->{'response'} as $exchange => $data){
                $listQuotes[$exchange] = $data;
            }
        }
        unset($store);
        unset($interface);
        return $listQuotes;
    }

/Autoloader.php

<?php
namespace App\Worker;

class Autoloader extends \Worker
{

    protected $loader;

    public function __construct($loader)
    {
        $this->loader = $loader;
    }

    /* включить автозагрузчик для задач */
    public function run()
    {
        require_once($this->loader);
    }

    /* переопределить поведение наследования по умолчанию для нового потокового контекста */
    public function start(int $options = PTHREADS_INHERIT_ALL)
    {
        return parent::start(PTHREADS_INHERIT_NONE);
    }

}

/Autoloadable.php

<?php
namespace App\Worker;

/* нормальный, автоматически загруженный класс */

class Autoloadable
{
    public $response;

    public function __construct($greeting)
    {
        $this->response = $greeting->job();
    }
}

/Task.php

<?php
namespace App\Worker;

class Task extends \Threaded
{
    protected $greeting;
    protected $result;

    public function __construct($greeting,\Threaded $store)
    {
        $this->greeting = $greeting;
        $this->result = $store;
    }

    public function run()
    {
        $greeting = new Autoloadable($this->greeting);
        $this->result[] = $greeting;
    }
}

how do I pass the right doctrine to be able to work with it from the job?

there's a very similar question on github but I can't deal with it. https://github.com/krakjoe/pthreads/issues/369

Have you tried requiring an ObjectManager instance in the __construct of Task (your last code block)?

Have a read of this article

Cannot test it atm, don't have zts setup, but I've used this to great success in other projects.

I would expect you need to do something like:

$pool = new Pool(4);

for ($i = 0; $i < 15; ++$i) {
    $pool->submit(new class($objectManager) extends \Threaded
    {
        private $objectManager;

        public function __construct(ObjectManager $objectManager)
        {
            $this->objectManager= $objectManager;
        }

        public function run()
        {
            // obviously replace the contents of this function
            $this->objectManager->performTask; 
            echo 'Job\'s done.' . PHP_EOL;
        }
    });
}

while ($pool->collect());

$pool->shutdown();

The instantiation of the new anonymous class takes the $objectManager present in your current instance, like /console_comand.php there, and passes it to this new anonymous class to fulfill the __construct requirements.

The linked article does a better job of explaining it than I do, so please give it a read.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM