Daemon, detach and run in the background
@param \Closure|null $beforeQuit
@return int Return new process PID
@throws \RuntimeException
423081
public static function daemonRun(\Closure $beforeQuit = null): int
    {
        if (!self::hasPcntl()) {
            return 0;
        }

        // umask(0);
        $pid = \pcntl_fork();

        switch ($pid) {
            case 0: // at new process
                $pid = self::getPid();

                if (posix_setsid() < 0) {
                    throw new \RuntimeException('posix_setsid() execute failed! exiting');
                }

                // chdir('/');
                // umask(0);
                break;

            case -1: // fork failed.
                throw new \RuntimeException('Fork new process is failed! exiting');
                break;

            default: // at parent
                if ($beforeQuit) {
                    $beforeQuit($pid);
                }

                exit;
        }

        return $pid;
    }
880076
public function before($callback, $priority = 0)
    {
        //        $app = $this;
        $container = $this->container;

        $this->on(KernelEvents::REQUEST, function (GetResponseEvent $event) use ($callback, $container) {
            if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
                return;
            }

            $ret = call_user_func($container['callback_resolver']->resolveCallback($callback), $event->getRequest(), $container);

            if ($ret instanceof Response) {
                $event->setResponse($ret);
            }
        }, $priority);
    }
459955
public function runCallback(\Closure $callback)
    {
        // Check if a legacy stack callback is already running.
        if ($this->runningCallback) {
            throw new RuntimeException('Started recursive callback in legacy kernel.');
        }

        // Set the callback as running.
        $this->runningCallback = true;

        // Change current directory to the legacy stack.
        $platformHome = getcwd();
        // @todo Must get innomatic_legacy path from configuration.
        chdir($platformHome . '/innomatic_legacy');

        try {
            // Start the legacy Root Container and the legacy autoloader.
            require_once getcwd().'/innomatic/core/classes/innomatic/core/RootContainer.php';
            $rootContainer = \Innomatic\Core\RootContainer::instance('\Innomatic\Core\RootContainer');

            // Add the Symfony service container
            $rootContainer->setServiceContainer($this->container);

            // Start the legacy Innomatic Container.
            $innomatic = \Innomatic\Core\InnomaticContainer::instance('\Innomatic\Core\InnomaticContainer');

            // Set the Innomatic interface type to console.
            $innomatic->setInterface(\Innomatic\Core\InnomaticContainer::INTERFACE_CONSOLE);
            $home = \Innomatic\Core\RootContainer::instance('\Innomatic\Core\RootContainer')
                ->getHome()
                . 'innomatic/';

            // Start Innomatic.
            $innomatic->bootstrap($home, $home . 'core/conf/innomatic.ini');
            
            // Run the callback in the legacy core.
            $result = $innomatic->runCallback($callback);
        } catch (Exception $e) {
            // Go back to the new platform home.
            chdir($platformHome);
        
            // Clean the callback running state.
            $this->runningCallback = false;
            throw $e;
        }

        // Go back to the new platform home.
        chdir($platformHome);

        // Clean the callback running state.
        $this->runningCallback = false;

        return $result;
    }
982140
protected function initQueue()
	{
		if ($this->beingDestroyed) {
			throw new \RuntimeException(self::ERROR_BEING_DESTROY);
		}
		$this->idleQueue = new \SplQueue();
		$this->taskQueue = new \SplQueue();
		
		return $this;
	}
576647
private function runCommand(Process $process)
    {
        $output = $this->output;

        /** @type DebugFormatterHelper $debugFormatter */
        $debugFormatter = $this->getHelperSet()->get('debug_formatter');
        if (null !== $dispatcher = $this->getEventDispatcher()) {
            $event = new PreExecuteEvent($this, $process);
            $dispatcher->dispatch(Event::PRE_EXECUTE, $event);

            if ($event->isPropagationStopped()) {
                $output->writeln(
                    ['', sprintf('    <info>[%s]</info> - <comment>Stopped</comment>', $this->getName()), '']
                );

                return true;
            }
        }

        if ($output->getVerbosity() === OutputInterface::VERBOSITY_VERBOSE || $this->getParameter('dry_run')) {
            $output->writeln('        // '.$process->getCommandLine());
        }

        if ($this->getParameter('dry_run')) {
            return true;
        }

        if ($this->hasParameter('cwd')) {
            $process->setWorkingDirectory($this->getParameter('cwd'));
        }

        if ($output->getVerbosity() === OutputInterface::VERBOSITY_VERY_VERBOSE) {
            $output->writeln(
                sprintf(
                    '        // Setting timeout for %d seconds.',
                    $this->getParameter('timeout')
                )
            );
        }
        $process->setTimeout($this->getParameter('timeout') !== 0 ? $this->getParameter('timeout') : null);

        if ($this->hasParameter('output')) {
            $append = $this->hasParameter('append') && $this->getParameter('append') ? 'a' : 'w';
            $stream = fopen($this->getParameter('output'), $append);
            $output = new StreamOutput($stream, StreamOutput::VERBOSITY_NORMAL, true);
        }

        $output->writeln(
            $debugFormatter->start(
                spl_object_hash($process),
                $process->getCommandLine()
            )
        );

        $process->start();

        return $process;
    }
979838
public function pipe($middleware, ?int $priority = 1, ?string $before = null)
    {
        if(is_object($middleware)) {
            $class = get_class($middleware);
        } else if(is_string($middleware) && class_exists($middleware)) {
            $class = $middleware;
        }
        if(isset($class) && ! isset($this->middlewareClasses[$class])) {
            $this->middlewareClasses[$class] = $middleware;
        }

        $this->getMiddlewareGroup()->addMiddleware($middleware, $priority, $before);
    }
409239
public function envRestart()
    {
        $this->executeCommandHook(__FUNCTION__, 'before');
        $this->engineInstance()->restart();
        $this->executeCommandHook(__FUNCTION__, 'after');

        return $this;
    }
509673
public function dispatch(\Closure $task, $middlewares = null)
    {
        is_array($middlewares) || $middlewares = $this->getMiddlewares();

        $beforeReturnValue = $this->before($middlewares);

        if ($beforeReturnValue === false || $beforeReturnValue !== true) {
            return $beforeReturnValue;
        }

        $this->setPayload($task());

        $afterReturnValue = $this->after(array_reverse($middlewares));

        if ($afterReturnValue === false || $afterReturnValue !== true) {
            return $afterReturnValue;
        }

        return $this->getPayload();
    }
335683
public function before(\Closure $closure = null)
    {
        if (null !== $closure) {
            $this->before[] = $closure;

            return $this;
        }

        return $this->before[] = new ExprBuilder($this->node);
    }
145850
public function beforeDetach()
    {
        $handler = $this->get('handler');
        if (class_exists($handler)) {
            $handler = new $handler();

            return $handler->beforeDetach($this);
        }
    }
1318431
public function exec($cmd): ProcessStatus
    {
        $cmd = sprintf('%s %s', $this->phpBinaryPath, $cmd . ' &');
        if (PHP_OS === 'WINNT') {
            $cmd = str_replace('/', '\\', $cmd);
            $cmd = str_replace('\\', '\\\\', $cmd);
        }
        if (PHP_SAPI !== 'cli') {
//            define('STDIN', fopen('php://stdin', 'r'));
            define('STDOUT', fopen('php://stdout', 'w'));
            define('STDERR', fopen('php://stderr', 'w'));
        }
        $pipes = [['pipe', 'r'], STDOUT, STDERR];
        $pipesOpened = [];
        Log::log($cmd);
        $resource = proc_open($cmd, $pipes, $pipesOpened, null, null, ['bypass_shell' => true]);
        if (false === $resource) {
            throw new \RuntimeException('Cannot be run ' . $cmd);
        }
        return new ProcessStatus($resource, $pipesOpened);
    }
984000
public function beforeSending(Closure $callback): self
    {
        return tap($this, function () use ($callback) {
            $this->beforeSendingCallbacks[] = $callback;
        });
    }
193561
private function preProcess(AbstractInvoke $invoke): AbstractInvoke
    {
        $result = $this->preProcess->handle(new ProcessorContainer($this, $invoke));

        if ($result instanceof ProcessorContainer) {
            return $result->getInvoke();
        }

        throw new \RuntimeException();
    }
224050
protected function fork()
	{
		// Attempt to fork the process.
		$pid = $this->pcntlFork();

		// If the fork failed, throw an exception.
		if ($pid === -1)
		{
			throw new \RuntimeException('The process could not be forked.');
		}

		if ($pid === 0)
		{
			// Update the process id for the child.
			$this->processId = (int) posix_getpid();
		}
		else
		{
			// Log the fork in the parent.
			$this->getLogger()->debug('Process forked ' . $pid);
		}

		// Trigger the onFork event.
		$this->postFork();

		return $pid;
	}
782354
public function setTruncateBefore(int $truncateBefore): StreamMetadataBuilder
    {
        if ($truncateBefore < 0) {
            throw new InvalidArgumentException('Truncate before must be positive');
        }

        $this->truncateBefore = $truncateBefore;

        return $this;
    }
315308
public function beforeProcess()
    {
        $event = new ProcessEvent($this->message, $this->getWechat());
        $this->trigger(self::EVENT_BEFORE_PROCESS, $event);
        return $event->isValid;
    }
869751
private function runGateBefore(array $before_permissions)
    {
        $this->gate->before(function ($user, $ability) use ($before_permissions) {
            $result = true;
            foreach ($before_permissions as $restriction) {
                if (is_array($restriction)) {
                    $policy = reset($restriction);
                    $operator = key($restriction);
                } else {
                    $policy = $restriction;
                    $operator = 'and';
                }

                if (is_callable($policy)) {
                    $policy_method_return = call_user_func($policy, $user, $ability);
                } else {
                    list($class, $method) = explode('@', $policy);
                    $policy_method_return = app($class)->$method($user, $ability); // should return boolean
                }

                if ($operator === 'or' || $operator === '||') {
                    $result = $result || $policy_method_return;
                } else {
                    $result = $result && $policy_method_return;
                }
            }
            if ($result == true) {
                return true;
            }
        });
    }