A
A
artzwinger2019-01-09 13:27:57
PHP
artzwinger, 2019-01-09 13:27:57

Is it possible to cross memory in PCNTL PHP forks?

There is a PHP daemon that runs in Magento forks to print PDF (custom functionality that works fine when printing manually from the admin).

class Generate_Pdf_Command extends Mage_Shell_Abstract
{
    const SLEEP_TIME_SEC = 0.2;
    const TIME_LIMIT = 600;
    protected $_startTime;
    protected $_childProcessList = [];

    public function __construct()
    {
        $this->_parseArgs();
        $this->_validate();
    }

    public function run()
    {
        $this->_startTime = time();
        while (true) {
            usleep(self::SLEEP_TIME_SEC * 1000);
            $current = time();
            if ($current - $this->_startTime >= self::TIME_LIMIT) {
                exit(0);
            }

            $pid = pcntl_fork();
            if ($pid === -1) {
                $this->_printErr('Can\'t use forks.');
                exit(0);
            }

            if ($pid) {
                $this->_processMain($pid);
                continue;
            }

            $this->_processChild();
            exit(0);
        }
    }

    protected function _processMain($pid)
    {
        $this->_childProcessList[$pid] = true;
        if ($this->_canFork()) {
            return;
        }
        $signPid = pcntl_wait($status);
        if (isset($this->_childProcessList[$signPid])) {
            unset($this->_childProcessList[$signPid]);
        } else {
            $this->_childProcessList = [];
        }
    }

    protected function _processChild()
    {
        try {
            (new Generate_Pdf)->run();
        } catch (Throwable $e) {
            $this->_printErr($e->getMessage());
        }
    }

    protected function _canFork()
    {
        return count($this->_childProcessList) < $this->getArg('children');
    }

    protected function _printLn($msg)
    {
        fwrite(STDOUT, $msg.PHP_EOL);
    }

    protected function _printErr($msg)
    {
        fwrite(STDERR, $msg.PHP_EOL);
    }
}

As you can see, Magento does not run in the main process, and the abstract shell class is used only for parsing arguments. How to debug it? Played occasionally.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question