Spork\ProcessManager::fork PHP Method

fork() public method

Forks something into another process and returns a deferred object.
public fork ( $callable )
    public function fork($callable)
    {
        if (!is_callable($callable)) {
            throw new UnexpectedTypeException($callable, 'callable');
        }
        // allow the system to cleanup before forking
        $this->dispatcher->dispatch(Events::PRE_FORK);
        if (-1 === ($pid = pcntl_fork())) {
            throw new ProcessControlException('Unable to fork a new process');
        }
        if (0 === $pid) {
            // reset the list of child processes
            $this->forks = array();
            // setup the shared memory
            $shm = $this->factory->createSharedMemory(null, $this->signal);
            $message = new ExitMessage();
            // phone home on shutdown
            register_shutdown_function(function () use($shm, $message) {
                $status = null;
                try {
                    $shm->send($message, false);
                } catch (\Exception $e) {
                    // probably an error serializing the result
                    $message->setResult(null);
                    $message->setError(Error::fromException($e));
                    $shm->send($message, false);
                    exit(2);
                }
            });
            // dispatch an event so the system knows it's in a new process
            $this->dispatcher->dispatch(Events::POST_FORK);
            if (!$this->debug) {
                ob_start();
            }
            try {
                $result = call_user_func($callable, $shm);
                $message->setResult($result);
                $status = is_integer($result) ? $result : 0;
            } catch (\Exception $e) {
                $message->setError(Error::fromException($e));
                $status = 1;
            }
            if (!$this->debug) {
                $message->setOutput(ob_get_clean());
            }
            exit($status);
        }
        // connect to shared memory
        $shm = $this->factory->createSharedMemory($pid);
        return $this->forks[$pid] = $this->factory->createFork($pid, $shm, $this->debug);
    }

Usage Example

Beispiel #1
0
 public function testRunningDaemonWithResistingWorker()
 {
     $writer = $this->getFileWriter();
     $fork = $this->outerManager->fork(function () use($writer) {
         $handler = new NullHandler();
         $builder = new Builder(array('worker1' => function () use($writer) {
             $writer("worker1.call");
         }, 'worker2' => array('startup' => function () use($writer) {
             pcntl_signal(SIGQUIT, SIG_IGN);
             pcntl_signal(SIGINT, SIG_IGN);
             $writer("worker2.startup");
         }, 'loop' => function () use($writer) {
             $writer("worker2.call");
         }, 'interval' => 1)));
         $builder->setLogger(new Logger('test', array($handler)))->setShutdownTimeout(3);
         $daemon = $builder->build();
         $daemon->setProcessName('testing');
         $daemon->run();
     });
     sleep(1);
     $start = time();
     $fork->kill(SIGQUIT);
     while (posix_kill($fork->getPid(), 0)) {
         pcntl_waitpid($fork->getPid(), $status, WNOHANG | WUNTRACED);
         usleep(100000);
     }
     $end = time();
     $diff = $end - $start;
     $this->assertTrue($diff >= 2 && $diff <= 4, 'Has been killed in shutdown interval');
     $content = file_get_contents($this->tempFile);
     $this->assertSame(1, preg_match_all('/worker1\\.call/', $content));
     $this->assertSame(1, preg_match_all('/worker2\\.startup/', $content));
     $calls = preg_match_all('/worker2\\.call/', $content);
     $this->assertTrue($calls >= 3 && $calls <= 5, 'Expected amount of worker2 calls');
 }
All Usage Examples Of Spork\ProcessManager::fork