public function onReady() { $appInstance = $this; Daemon_TimedEvent::add(function ($event) use($appInstance) { $appInstance->broadcastCall('hello', array(Daemon::$process->pid)); $event->finish(); }, pow(10, 6) * 2); }
public function addWatch($path, $subscriber, $flags = NULL) { $path = realpath($path); if (!isset($this->files[$path])) { $this->files[$path] = array(); if ($this->inotify) { $this->descriptors[inotify_add_watch($this->inotify, $path, $flags ?: IN_MODIFY)] = $path; } } $this->files[$path][] = $subscriber; Daemon_TimedEvent::setTimeout('fileWatcherTimedEvent'); return true; }
/** * Runtime of Master process * @return void */ protected function run() { Daemon::$process = $this; $this->prepareSystemEnv(); gc_enable(); $this->eventBase = event_base_new(); $this->registerEventSignals(); $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->spawnWorkers(min(Daemon::$config->startworkers->value, Daemon::$config->maxworkers->value)); Daemon_TimedEvent::add(function ($event) { $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); } $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, 'MPMTimedEvent'); while (!$this->breakMainLoop) { event_base_loop($this->eventBase); } }
/** * Called when request iterated. * @return integer Status. */ public function run() { if (!$this->started) { $this->started = true; $LockClient = Daemon::$appResolver->getInstanceByAppName('LockClient'); $req = $this; $LockClient->job('ExampleJobName', false, function ($command, $jobname, $client) use($req) { if ($command === 'RUN') { Daemon_TimedEvent::add(function ($event) use($req, $jobname, $client) { Daemon::log('done'); $client->done($jobname); $req->out(':-)'); $req->wakeup(); $event->finish(); }, pow(10, 6) * 1); } else { $req->out(':-('); $req->wakeup(); } }); $this->sleep(5); //timeout } }
public function onPacket($p) { if ($p['op'] === 'spawnInstance') { $fullname = $p['appfullname']; $fullname = str_replace('-', ':', $fullname); if (strpos($fullname, ':') === false) { $fullname .= ':'; } list($app, $name) = explode(':', $fullname, 2); Daemon::$appResolver->appInstantiate($app, $name); } elseif ($p['op'] === 'importFile') { $path = $p['path']; Daemon_TimedEvent::add(function ($event) use($path) { $self = Daemon::$process; if (Daemon::supported(Daemon::SUPPORT_RUNKIT_IMPORT)) { runkit_import($path, RUNKIT_IMPORT_FUNCTIONS | RUNKIT_IMPORT_CLASSES | RUNKIT_IMPORT_OVERRIDE); } else { $this->appInstance->log('Cannot import \'' . $path . '\': runkit_import is not callable.'); } $event->finish(); }, 5); } elseif ($p['op'] === 'call') { if (strpos($p['appfullname'], '-') === false) { $p['appfullname'] .= '-'; } list($app, $name) = explode('-', $p['appfullname'], 2); if ($app = Daemon::$appResolver->getInstanceByAppName($app, $name)) { $app->RPCall($p['method'], $p['args']); } } }
/** * Called when the connection has got new data * @param resource Descriptor * @param mixed Attacted variable * @return void */ public function onReadEvent($stream, $arg) { $connId = is_array($arg) ? $arg[0] : array_search($stream, Daemon::$process->pool, TRUE); if (Daemon::$config->logevents->value) { Daemon::$process->log(get_class($this) . '::' . __METHOD__ . '(' . $connId . ') invoked. ' . Debug::dump(Daemon::$process->pool[$connId])); } if ($this->queuedReads) { Daemon::$process->readPoolState[$connId] = TRUE; Daemon_TimedEvent::setTimeout('readPoolEvent'); } $success = FALSE; if (isset($this->sessions[$connId])) { if ($this->sessions[$connId]->readLocked) { return; } while (($buf = $this->read($connId, $this->readPacketSize)) !== FALSE) { $success = TRUE; $this->sessions[$connId]->stdin($buf); } } }
/** * @todo description? * @param boolean - Hard? If hard, we shouldn't wait for graceful shutdown of the running applications. * @return boolean - Ready? */ public function shutdown($hard = FALSE) { if (Daemon::$config->logevents->value) { $this->log('event shutdown(' . ($hard ? 'HARD' : '') . ') invoked.'); } if (Daemon::$config->throwexceptiononshutdown->value) { throw new Exception('event shutdown'); } @ob_flush(); if ($this->terminated === TRUE) { if ($hard) { exit(0); } return; } $this->terminated = TRUE; $this->closeSockets(); $this->setStatus(3); if ($hard) { exit(0); } $this->reloadReady = $this->appInstancesReloadReady(); if ($this->reload === TRUE) { $this->reloadReady = $this->reloadReady && microtime(TRUE) > $this->reloadTime; } if (Daemon::$config->logevents->value) { $this->log('reloadReady = ' . Debug::dump($this->reloadReady)); } foreach ($this->queue as $r) { if ($r instanceof stdClass) { continue; } if ($r->running) { $r->finish(-2); } } $n = 0; unset($this->timeouts['checkStateTimedEvent']); Daemon_TimedEvent::add(function ($event) { $self = Daemon::$process; $self->reloadReady = $self->appInstancesReloadReady(); if ($self->reload === TRUE) { $self->reloadReady = $self->reloadReady && microtime(TRUE) > $self->reloadTime; } if (!$self->reloadReady) { $event->timeout(); } else { event_base_loopexit($self->eventBase); } }, 1000000.0, 'checkReloadReady'); while (!$this->reloadReady) { event_base_loop($this->eventBase); } posix_kill(posix_getppid(), SIGCHLD); exit(0); }
public final function baz() { return function ($jobname, $job) { Daemon_TimedEvent::add(function ($event) use($jobname, $job) { // Job done $job->setResult($jobname, array('job' => 'baz', 'success' => false, 'line' => __LINE__)); $event->finish(); }, 1000.0 * 300); }; }
public function onPacket($p) { if ($p['op'] === 'spawnInstance') { $fullname = $p['appfullname']; if (strpos($fullname, '-') === false) { $fullname .= '-'; } list($app, $name) = explode('-', $fullname, 2); Daemon::$appResolver->appInstantiate($app, $name); } elseif ($p['op'] === 'importFile') { $path = $p['path']; Daemon_TimedEvent::add(function ($event) use($path) { $self = Daemon::$process; runkit_import($path, RUNKIT_IMPORT_FUNCTIONS | RUNKIT_IMPORT_CLASSES | RUNKIT_IMPORT_OVERRIDE); $event->finish(); }, 5); } elseif ($p['op'] === 'call') { if (strpos($p['appfullname'], '-') === false) { $p['appfullname'] .= '-'; } list($app, $name) = explode('-', $p['appfullname'], 2); if ($app = Daemon::$appResolver->getInstanceByAppName($app, $name)) { $app->RPCall($p['method'], $p['args']); } } }