Fork into the background

@param string $mode return realm label provider
@param array $workerConfig optional.
@param bool $lock optional. false gives no lock protection, true re-locks on $this->lock
172315
protected function fork(string $mode, array $workerConfig = null, bool $lock = false) {

        $modes = [
            'daemon' => [
                'parent' => 'console',
                'child' => 'daemon'
            ],
            'fleet' => [
                'parent' => 'daemon',
                'child' => 'worker'
            ]
        ];
        if (!array_key_exists($mode, $modes)) {
            return false;
        }

        // Fork
        $pid = pcntl_fork();

        if ($pid > 0) {

            $realm = val('parent', $modes[$mode]);

            // Parent
            $this->log(LogLevel::DEBUG, "[{pid}] Parent ({$realm})");

            // Record child PID
            $childRealm = val('child', $modes[$mode]);
            $this->children[$pid] = $childRealm;

            // Inform payload of new child
            $this->payloadExec('spawnedWorker', [$pid, $realm, $workerConfig]);

            // Return as parent
            return $realm;

        } else if ($pid == 0) {

            $this->realm = val('child', $modes[$mode]);

            // Child
            $this->log(LogLevel::DEBUG, "[{pid}] Child ({$this->realm})");

            // Re-lock process
            if ($lock) {
                $this->log(LogLevel::DEBUG, "[{pid}]   locking child process");
                $locked = $this->lock->lock();
                if (!$locked) {
                    $this->log(Daemon::LOG_L_WARN, "[{pid}] Unable to lock forked process");
                    exit;
                }
            }

            // Detach
            $this->log(LogLevel::DEBUG, "[{pid}]   detach from {parent}", [
                'parent' => $modes[$mode]['parent']
            ]);
            if (posix_setsid() == -1) {
                $this->log(LogLevel::DEBUG, "[{pid}] Unable to detach from {parent}", [
                    'parent' => $modes[$mode]['parent']
                ]);
                exit;
            }

            // SETGID/SETUID
            $sysGroup = $this->get('runasgroup', null);
            if (!is_null($sysGroup)) {

                $sysGroupInfo = posix_getgrnam($sysGroup);
                if (is_array($sysGroupInfo)) {
                    $sysGID = val('gid', $sysGroupInfo, null);
                    if (!is_null($sysGID)) {
                        $sysSetegid = posix_setegid($sysGID);
                        $sysSetegid = $sysSetegid ? 'success' : 'failed';
                    }
                    $this->log(LogLevel::DEBUG, "[{pid}]   setegid... {$sysSetegid}");
                } else {
                    $this->log(LogLevel::WARNING, "[{pid}]   setegid, no such group '{$sysGroup}'");
                }
            }

            $sysUser = $this->get('runasuser', null);
            if (!is_null($sysUser)) {
                $sysUserInfo = posix_getpwnam($sysUser);
                if (is_array($sysUserInfo)) {
                    $sysUID = val('uid', $sysUserInfo, null);
                    if (!is_null($sysUID)) {
                        $sysSeteuid = posix_seteuid($sysUID);
                        $sysSeteuid = $sysSeteuid ? 'success' : 'failed';
                    }
                    $this->log(LogLevel::DEBUG, "[{pid}]   seteuid... {$sysSeteuid}");
                } else {
                    $this->log(LogLevel::WARN, "[{pid}]   seteuid, no such user '{$sysUser}'");
                }
            }

            // Close resources
            /*
            $this->log(LogLevel::DEBUG, "[{pid}]   close console I/O");
            fclose(STDIN);
            fclose(STDOUT);
            fclose(STDERR);
            */

            // Return as child
            return $this->realm;

        } else {

            // Failed
            $this->log(LogLevel::ERROR, "[{pid}] Failed to fork process");
            exit(1);

        }
    }
245010
public synchronized boolean lock() throws KeeperException, InterruptedException {
        if (isClosed()) {
            return false;
        }
        ensurePathExists(dir);

        return (Boolean) retryOperation(zop);
    }
1064528
public function lock($document, $lockMode, $lockVersion = null)
    {
        if (!is_object($document)) {
            throw new \InvalidArgumentException(gettype($document));
        }
        $this->unitOfWork->lock($document, $lockMode, $lockVersion);
    }
947942
public function schedule($workerClass, array $args = [], $retry = false, float $priority = 0, $at = null)
    {
        $key = $this->queue->generateListKey();
        if ($this->id === null) {
            try {
                $uuid = Uuid::uuid4();
                $jobId = $uuid->toString();
                $this->id = $jobId;
            } catch (UnsatisfiedDependencyException $e) {
                throw new FailedToCreateJobIdException('An error occured when generating the JobID');
            }
        }
        $id = "$key:" . $this->id;

        $result = $this->queue->getClient()->getRedis()->multi()
            ->hMset($id, [
                'workerClass' => $workerClass,
                'retry' => \gettype($retry) . ':' . $retry,
                'priority' => $at ?? $priority,
                'args' => \json_encode($args)
            ])
            ->zincrby(($at === null ? $key : $key . '-scheduled'), (float)($at ?? $priority), $id)
            ->exec();

        // If the queue and hash were added, hydrate the model then return true
        if ($result[0] === true) {
            $this->workerClass = $workerClass;
            $this->args = $args;
            $this->retry = $retry;
            $this->priority = $priority;
            return true;
        } else {
            // If the job was not added to the queue, remove the hash
            $this->cancel();
            return false;
        }

        return false;
    }
1219765
protected function listenToWorker(Worker $worker)
    {
        $worker->getDispatcher()
            ->listen('onWorkerBeforeJobRun', function (Event $event) {
                /**
                 * @var JobInterface $job
                 * @var QueueMessage $message
                 */
                $job     = $event['job'];
                $message = $event['message'];

                $this->console->addMessage(sprintf(
                    'Run Job: <info>%s</info> - Message ID: <info>%s</info>',
                    $job->getName(),
                    $message->getId()
                ));
            })
            ->listen('onWorkerJobFailure', function (Event $event) {
                /**
                 * @var JobInterface $job
                 * @var \Exception   $e
                 * @var QueueMessage $message
                 */
                $job     = $event['job'];
                $e       = $event['exception'];
                $message = $event['message'];

                $this->console->addMessage(sprintf(
                    'Job %s failed: %s (%s)',
                    $job->getName(),
                    $e->getMessage(),
                    $message->getId()
                ), 'error');

                // If be deleted, send to failed table
                if ($message->isDeleted()) {
                    $this->console->container->get('queue.failer')->add(
                        $this->console->get('queue.connection', 'sync'),
                        $message->getQueueName(),
                        json_encode($message),
                        (string) $e
                    );
                }

                $this->console->handleException($e);
            })
            ->listen('onWorkerLoopCycleStart', function (Event $event) {
                /** @var Worker $worker */
                $worker = $event['worker'];

                switch ($worker->getState()) {
                    case $worker::STATE_ACTIVE:
                        if ($this->console->isOffline()) {
                            $worker->setState($worker::STATE_PAUSE);
                        }
                        break;

                    case $worker::STATE_PAUSE:
                        if ($this->console->isOffline()) {
                            $worker->setState($worker::STATE_ACTIVE);
                        }
                        break;
                }
            })
            ->listen('onWorkerLoopCycleFailure', function (Event $event) {
                /** @var \Exception $e */
                $e = $event['exception'];

                $this->console->addMessage(
                    sprintf(
                        '%s File: %s (%s)',
                        $e->getMessage(),
                        $e->getFile(),
                        $e->getLine()
                    ),
                    'error'
                );

                $this->console->handleException($e);

                if ($this->console->database instanceof AbstractDatabaseDriver) {
                    $this->console->database->disconnect();
                }
            })
            ->listen('onWorkerLoopCycleEnd', function (Event $event) {
                /** @var QueueManager $manager */
                $manager = $event['manager'];

                $driver = $manager->getDriver();

                if ($driver instanceof DatabaseQueueDriver) {
                    $driver->disconnect();
                }

                if ($this->console->database instanceof AbstractDatabaseDriver) {
                    $this->console->database->disconnect();
                }
            });
    }
1127452
public function lock($uri, LockInfo $lockInfo)
    {
        // We're making the lock timeout 30 minutes
        $lockInfo->timeout = 30 * 60;
        $lockInfo->created = time();
        $lockInfo->uri = $uri;

        $locks = $this->getLocks($uri, false);
        $exists = false;
        foreach ($locks as $lock) {
            if ($lock->token == $lockInfo->token) {
                $exists = true;
            }
        }

        if ($exists) {
            $stmt = $this->pdo->prepare('UPDATE '.$this->tableName.' SET owner = ?, timeout = ?, scope = ?, depth = ?, uri = ?, created = ? WHERE token = ?');
            $stmt->execute([
                $lockInfo->owner,
                $lockInfo->timeout,
                $lockInfo->scope,
                $lockInfo->depth,
                $uri,
                $lockInfo->created,
                $lockInfo->token,
            ]);
        } else {
            $stmt = $this->pdo->prepare('INSERT INTO '.$this->tableName.' (owner,timeout,scope,depth,uri,created,token) VALUES (?,?,?,?,?,?,?)');
            $stmt->execute([
                $lockInfo->owner,
                $lockInfo->timeout,
                $lockInfo->scope,
                $lockInfo->depth,
                $uri,
                $lockInfo->created,
                $lockInfo->token,
            ]);
        }

        return true;
    }
369745
public static function instance($mode=NULL){
        if(empty($mode)){
            if(defined("QUEUE_CONSUMER") && constant("QUEUE_CONSUMER")){
                $mode = QUEUE_CONSUMER;
            }else{
                $mode = 'fork';
            }
        }
        
        if(!isset(self::$__instance[$mode])){
            if($instance = new self($mode)){
                self::$__instance[$mode] = $instance;
                return self::$__instance[$mode];
            }else{
                return false;
            }
        }else{
            return self::$__instance[$mode];
        }
    }
499457
protected function resolve(Lock $lock, $action, Resource $resource = null)
    {
        // If no resource was set for this permission we'll only need to check the action.
        if ($this->resource === null || $this->resource->getResourceType() === null) {
            return $this->matchesAction($action) && $this->resolveConditions($lock, $action, $resource);
        }

        return (
            $this->matchesAction($action) &&
            $this->matchesResource($resource) &&
            $this->resolveConditions($lock, $action, $resource)
        );
    }
1174855
public function lock($document, $lockMode, $lockVersion = null)
    {
        if ($this->getDocumentState($document) != self::STATE_MANAGED) {
            throw new \InvalidArgumentException("Document is not MANAGED.");
        }

        $documentName = get_class($document);
        $class = $this->dm->getClassMetadata($documentName);

        if ($lockMode == LockMode::OPTIMISTIC) {
            if ( ! $class->isVersioned) {
                throw LockException::notVersioned($documentName);
            }

            if ($lockVersion != null) {
                $documentVersion = $class->reflFields[$class->versionField]->getValue($document);
                if ($documentVersion != $lockVersion) {
                    throw LockException::lockFailedVersionMissmatch($document, $lockVersion, $documentVersion);
                }
            }
        } elseif (in_array($lockMode, array(LockMode::PESSIMISTIC_READ, LockMode::PESSIMISTIC_WRITE))) {
            $this->getDocumentPersister($class->name)->lock($document, $lockMode);
        }
    }
367634
public function configureBlocks($config, ContainerBuilder $container)
    {
        $container->setParameter('rz_search.block.search.class', $config['search']['class']);

        # template
        $temp = $config['search']['templates'];
        $templates = array();
        foreach ($temp as $template) {
            $templates[$template['path']] = $template['name'];
        }
        $container->setParameter('rz_search.block.search.templates.default', $templates);
    }
923486
public function setBlocking($toggle = true)
    {
        $ret = $toggle ? @socket_set_block($this->resource) : @socket_set_nonblock($this->resource);
        if ($ret === false) {
            throw Exception::createFromSocketResource($this->resource);
        }
        return $this;
    }
1343306
public function get_session_lock($rowid, $timeout) {
        parent::get_session_lock($rowid, $timeout);

        $fullname = $this->dbname.'-'.$this->prefix.'-session-'.$rowid;
        $sql = 'SELECT MOODLELIB.GET_LOCK(:lockname, :locktimeout) FROM DUAL';
        $params = array('lockname' => $fullname , 'locktimeout' => $timeout);
        $this->query_start($sql, $params, SQL_QUERY_AUX);
        $stmt = $this->parse_query($sql);
        $this->bind_params($stmt, $params);
        $result = oci_execute($stmt, $this->commit_status);
        if ($result === false) { // Any failure in get_lock() raises error, causing return of bool false
            throw new dml_sessionwait_exception();
        }
        $this->query_end($result, $stmt);
        oci_free_statement($stmt);
    }
73684
function startWorker(port) {
        var worker = child.fork(serverWorker, [
            '--port', port,
            '--server', serverFile,
            '--allowForcedExit', allowForcedExit,
            '--config', JSON.stringify(config.app || {}),
            '--title', workerTitle
        ]);

        worker.on('exit', createWorkerExitHandler(port));
        return worker;
    }
380080
public static function nblock($lock, \Closure $callback, $timeout = 120) {
        try {
            $redis = RedisClient::getRedis();
            if ($redis) {
                $cnt = $redis->incr($lock);
                if ($cnt != 1) {
                    return false;
                }
                $redis->setTimeout($lock, $timeout);
                try {
                    return $callback($redis);
                } catch (\Exception $e) {
                    log_warn($e->getMessage(), 'redis_lock');
                } finally {
                    $redis->decr($lock);
                }
            }
        } catch (\Exception $e) {
            log_warn($e->getMessage(), 'redis_lock');
        }

        return false;
    }
593556
private function executeInLock($lockName, callable $callback)
    {
        $this->res->getManagementLock()->lock($lockName);

        try {
            return call_user_func($callback);
        } finally {
            $this->res->getManagementLock()->unlock($lockName);
        }
    }
1246711
protected function _lockReferrer(KControllerContextInterface $context)
    {
        $cookie = $this->getObject('lib:http.cookie', array(
            'name'   => $this->_cookie_name.'_locked',
            'value'  => true,
            'path'   => $this->_cookie_path
        ));

        $context->response->headers->addCookie($cookie);
    }
296996
public function daemon($connectionName, $queue, WorkerOptions $options)
    {
        $lastRestart = $this->getTimestampOfLastQueueRestart();

        $this->registerSignalListener();

        while (true) {
            $this->registerTimeoutHandler($options);

            if ($this->daemonShouldRun($options)) {
                $this->runNextJob($connectionName, $queue, $options);
            } else {
                $this->sleep($options->sleep);
            }

            $this->callSignalHandler();

            if ($this->memoryExceeded($options->memory) ||
                $this->queueShouldRestart($lastRestart) ||
                $this->queueShouldExit()
            ) {
                $this->stop();
            }
        }
    }