Пример #1
0
 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);
 }
Пример #2
0
 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;
 }
Пример #3
0
 /**
  * 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);
     }
 }
Пример #4
0
 /**
  * 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
     }
 }
Пример #5
0
 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']);
         }
     }
 }
Пример #6
0
 /**
  * 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);
         }
     }
 }
Пример #7
0
 /**
  * @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);
 }
Пример #8
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);
     };
 }
Пример #9
0
 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']);
         }
     }
 }