Doctrine Entity Manager с PThreads и Symfony 4 - PullRequest
0 голосов
/ 04 февраля 2019

Я использую php-zts для параллельной обработки данных, используя symfony 4 и PThreads

Я отлично справляюсь с несколькими потоками, но у меня возникла проблема, мне нужен каждый из потоковчтобы иметь возможность работать с доктриной

Мне нужно убедиться, что каждый поток может работать с доктриной

Я пытался передать экземпляр контейнера напрямую, но он не будет работать, потому что онневозможно стерилизовать

/ 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;
    }
}

как передать правильное учение, чтобы иметь возможность работать с ним с работы?

есть очень похожий вопрос на github, но я не могу разобратьсяс этим.https://github.com/krakjoe/pthreads/issues/369

1 Ответ

0 голосов
/ 04 февраля 2019

Вы пытались запросить экземпляр ObjectManager в __construct из Task (ваш последний кодовый блок)?

Прочитайте эту статью

Невозможно протестировать ее, нет настройки zts, но я успешно использовал ее в других проектах.

Я ожидаю, что вам нужно сделать что-то вроде:

$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();

Для создания экземпляра нового анонимного класса требуется $objectManager, присутствующий в вашем текущем экземпляре, например /console_comand.php там, ипередает его этому новому анонимному классу для выполнения требований __construct.

Связанная статья лучше объясняет, чем я, поэтому, пожалуйста, прочитайте.

...