/** * Runtime of Master process * @return void */ public function run() { Daemon::$process = $this; $this->prepareSystemEnv(); class_exists('Timer'); // ensure loading this class gc_enable(); $this->eventBase = event_base_new(); $this->registerEventSignals(); FS::initEvent(); $this->fileWatcher = new FileWatcher(); $this->workers = new ThreadCollection(); $this->collections['workers'] = $this->workers; Daemon::$appResolver = (require Daemon::$config->path->value); $this->IPCManager = Daemon::$appResolver->getInstanceByAppName('IPCManager'); Daemon::$appResolver->preload(true); $this->callbacks = new SplStack(); $this->spawnWorkers(min(Daemon::$config->startworkers->value, Daemon::$config->maxworkers->value)); Timer::add(function ($event) use(&$cbs) { $self = Daemon::$process; static $c = 0; ++$c; if ($c > 0xfffff) { $c = 1; } if ($c % 10 == 0) { $self->workers->removeTerminated(true); gc_collect_cycles(); } else { $self->workers->removeTerminated(); } if (isset(Daemon::$config->mpm->value) && is_callable(Daemon::$config->mpm->value)) { call_user_func(Daemon::$config->mpm->value); } else { // default MPM $state = Daemon::getStateOfWorkers($self); if ($state) { $n = max(min(Daemon::$config->minspareworkers->value - $state['idle'], Daemon::$config->maxworkers->value - $state['alive']), Daemon::$config->minworkers->value - $state['alive']); if ($n > 0) { Daemon::log('Spawning ' . $n . ' worker(s).'); $self->spawnWorkers($n); event_base_loopbreak($self->eventBase); } $n = min($state['idle'] - Daemon::$config->maxspareworkers->value, $state['alive'] - Daemon::$config->minworkers->value); if ($n > 0) { Daemon::log('Stopping ' . $n . ' worker(s).'); $self->stopWorkers($n); } } } $event->timeout(); }, 1000000.0 * Daemon::$config->mpmdelay->value, 'MPM'); while (!$this->breakMainLoop) { while (!$this->callbacks->isEmpty()) { call_user_func($this->callbacks->shift(), $this); } event_base_loop($this->eventBase); } }
public function run() { proc_nice(Daemon::$settings['masterpriority']); gc_enable(); register_shutdown_function(array($this, 'onShutdown')); $this->collections = array('workers' => new threadCollection()); Thread::setproctitle(Daemon::$runName . ': master process' . (Daemon::$settings['pidfile'] !== Daemon::$settings['defaultpidfile'] ? ' (' . Daemon::$settings['pidfile'] . ')' : '')); Daemon::$appResolver = (require Daemon::$settings['path']); Daemon::$appResolver->preloadPrivileged(); $this->spawnWorkers(min(Daemon::$settings['startworkers'], Daemon::$settings['maxworkers'])); $mpmLast = time(); $autoReloadLast = time(); while (TRUE) { pcntl_signal_dispatch(); $this->sigwait(1, 0); clearstatcache(); if (Daemon::$logpointerpath !== Daemon::parseStoragepath(Daemon::$settings['logstorage'])) { $this->sigusr1(); } $c = 1; if (time() > $mpmLast + Daemon::$parsedSettings['mpmdelay']) { $mpmLast = time(); ++$c; if ($c > 0xfffff) { $c = 0; } if ($c % 10 == 0) { $this->collections['workers']->removeTerminated(TRUE); gc_collect_cycles(); } else { $this->collections['workers']->removeTerminated(); } if (isset(Daemon::$settings['mpm']) && is_callable($c = Daemon::$settings['mpm'])) { call_user_func($c); } else { $state = Daemon::getStateOfWorkers($this); if ($state) { $n = max(min(Daemon::$settings['minspareworkers'] - $state['idle'], Daemon::$settings['maxworkers'] - $state['alive']), Daemon::$settings['minworkers'] - $state['alive']); if ($n > 0) { Daemon::log('Spawning ' . $n . ' worker(s).'); $this->spawnWorkers($n); } $n = min($state['idle'] - Daemon::$settings['maxspareworkers'], $state['alive'] - Daemon::$settings['minworkers']); if ($n > 0) { Daemon::log('Stopping ' . $n . ' worker(s).'); $this->stopWorkers($n); } } } } } }