Example #1
0
 private static function registerLoopRunner()
 {
     $hasBeenRun = false;
     register_shutdown_function(function () use(&$hasBeenRun) {
         if (!$hasBeenRun) {
             EventLoop::getLoop()->run();
         }
     });
     static::$loop->nextTick(function () use(&$hasBeenRun) {
         $hasBeenRun = true;
     });
 }
Example #2
0
 /**
  * Returns the next free slave. This method is async, so be aware of async calls between this call.
  *
  * @return integer
  */
 protected function getNextSlave($cb)
 {
     $that = $this;
     $checkSlave = function () use($cb, $that, &$checkSlave) {
         $minConnections = null;
         $minPort = null;
         foreach ($this->slaves as $slave) {
             if (!$slave['ready']) {
                 continue;
             }
             if (!$this->concurrentRequestsPerWorker && $slave['busy']) {
                 //we skip workers that are busy, means worker that are currently handle a connection
                 //this makes it more robust since most applications are not made to handle
                 //several request at the same time - even when one request is streaming. Would lead
                 //to strange effects&crashes in high traffic sites if not considered.
                 //maybe in the future this can be set application specific.
                 //Rule of thumb: The application may not operate on globals, statics or same file paths to get this working.
                 continue;
             }
             // we pick a slave that currently handles the fewest connections
             if (null === $minConnections || $slave['connections'] < $minConnections) {
                 $minConnections = $slave['connections'];
                 $minPort = $slave['port'];
             }
         }
         if (null !== $minPort) {
             $cb($minPort);
             return;
         }
         $this->loop->futureTick($checkSlave);
     };
     $checkSlave();
 }
Example #3
0
 /**
  * Connects to ProcessManager, master process.
  */
 public function run()
 {
     $this->loop = \React\EventLoop\Factory::create();
     $this->errorLogger = BufferingLogger::create();
     ErrorHandler::register(new ErrorHandler($this->errorLogger));
     $client = stream_socket_client($this->config['controllerHost']);
     $this->controller = new \React\Socket\Connection($client, $this->loop);
     $pcntl = new \MKraemer\ReactPCNTL\PCNTL($this->loop);
     $pcntl->on(SIGTERM, [$this, 'shutdown']);
     $pcntl->on(SIGINT, [$this, 'shutdown']);
     register_shutdown_function([$this, 'shutdown']);
     $this->bindProcessMessage($this->controller);
     $this->controller->on('close', \Closure::bind(function () {
         $this->shutdown();
     }, $this));
     $this->server = new React\Server($this->loop);
     //our version for now, because of unix socket support
     $http = new HttpServer($this->server);
     $http->on('request', array($this, 'onRequest'));
     //port is only used for tcp connection. If unix socket, 'host' contains the socket path
     $port = $this->config['port'];
     $host = $this->config['host'];
     while (true) {
         try {
             $this->server->listen($port, $host);
             break;
         } catch (\React\Socket\ConnectionException $e) {
             usleep(500);
         }
     }
     $this->sendMessage($this->controller, 'register', ['pid' => getmypid(), 'port' => $port]);
     $this->loop->run();
 }
Example #4
0
 public function bye()
 {
     if ($this->connection->isWritable()) {
         $this->connection->write(json_encode(array('cmd' => 'unregister', 'pid' => getmypid())));
         $this->connection->close();
     }
     $this->loop->stop();
 }
Example #5
0
 private function setTimer()
 {
     $this->loop->addPeriodicTimer(1, function () {
         if ($this->getBridge() instanceof Bridges\TimerBridgeInterface) {
             $this->getBridge()->timer($this);
         }
     });
 }
Example #6
0
 /**
  * Construct.
  */
 public function __construct()
 {
     parent::__construct();
     $class = new \ReflectionClass('\\React\\EventLoop\\LibEventLoop');
     $property = $class->getProperty('eventBase');
     $property->setAccessible(true);
     $this->_eventBase = $property->getValue($this);
 }
Example #7
0
 public function create()
 {
     $that = $this;
     //todo: speed variable
     $this->loop->addReadStream(STDIN, function ($stdin) use($that) {
         $input = trim(fgets($stdin));
         if (in_array($input, Config::$commands)) {
             if ($input === 'exit') {
                 exit;
             } else {
                 $that->emit('action', [$input]);
             }
         } else {
             echo 'Unknown command' . PHP_EOL;
         }
         echo $that->prompt;
     });
     echo $this->getAsciiArt();
     echo PHP_EOL;
     echo $this->prompt;
 }
Example #8
0
 /**
  * Retry connecting to the transport
  */
 public function retryConnection()
 {
     $options = $this->reconnectOptions;
     if ($this->attemptRetry === false) {
         return;
     }
     if ($options['max_retries'] <= $this->retryAttempts) {
         return;
     }
     $this->retryAttempts++;
     if ($this->retryTimer >= $options['max_retry_delay']) {
         $this->retryTimer = $options['max_retry_delay'];
     } elseif ($this->retryTimer == 0) {
         $this->retryTimer = $options['initial_retry_delay'];
     } else {
         $this->retryTimer = $this->retryTimer * $options['retry_delay_growth'];
     }
     $this->loop->addTimer($this->retryTimer, function () {
         $this->transportProvider->startTransportProvider($this, $this->loop);
     });
 }
Example #9
0
 /**
  * Connects to ProcessManager, master process.
  */
 public function run()
 {
     $this->loop = \React\EventLoop\Factory::create();
     ErrorHandler::register(new ErrorHandler(new BufferingLogger()));
     $this->client = stream_socket_client('tcp://127.0.0.1:5500');
     $this->connection = new \React\Socket\Connection($this->client, $this->loop);
     $this->connection->on('error', function ($data) {
         var_dump($data);
     });
     $pcntl = new \MKraemer\ReactPCNTL\PCNTL($this->loop);
     $pcntl->on(SIGTERM, [$this, 'shutdown']);
     $pcntl->on(SIGINT, [$this, 'shutdown']);
     register_shutdown_function([$this, 'shutdown']);
     $this->bindProcessMessage($this->connection);
     $this->connection->on('close', \Closure::bind(function () {
         $this->shutdown();
     }, $this));
     $this->server = new \React\Socket\Server($this->loop);
     $this->server->on('error', function ($data) {
         var_dump($data);
     });
     $http = new HttpServer($this->server);
     $http->on('request', array($this, 'onRequest'));
     $http->on('error', function ($data) {
         var_dump($data);
     });
     $port = $this->config['port'];
     while (true) {
         try {
             $this->server->listen($port);
             break;
         } catch (\React\Socket\ConnectionException $e) {
             usleep(500);
         }
     }
     $this->sendMessage($this->connection, 'register', ['pid' => getmypid(), 'port' => $port]);
     $this->loop->run();
 }
Example #10
0
 /**
  * Registers a periodically triggered status event.
  */
 private function registerTimedEvents()
 {
     $this->reactLoop->addPeriodicTimer($this->config->getStatusLoopInterval(), function () {
         $memoryUsageMb = memory_get_usage(true) / 1024 / 1024;
         $this->runtimeStatistics->setMemoryUsageMb($memoryUsageMb);
         if ($memoryUsageMb > $this->config->getMemoryLimitMbWarn()) {
             $this->logger->warning("MemoryUsage:   {$memoryUsageMb} MB.");
         } else {
             if ($memoryUsageMb > $this->config->getMemoryLimitMbInfo()) {
                 $this->logger->info("MemoryUsage:   {$memoryUsageMb} MB.");
             }
         }
         $memoryPeakUsageMb = memory_get_peak_usage(true) / 1024 / 1024;
         $this->runtimeStatistics->setMemoryPeakUsageMb($memoryPeakUsageMb);
         if ($memoryPeakUsageMb > $this->config->getMemoryPeakLimitMbWarn()) {
             $this->logger->warning("MemoryPeakUsage " . memory_get_peak_usage(true) / 1024 / 1024 . " MB.");
         }
         $rateObjects = $this->runtimeStatistics->getAddedObjectRate($this->config->getStatusLoopInterval());
         $rateEvictions = $this->runtimeStatistics->getEvictionRate($this->config->getStatusLoopInterval());
         $this->logger->info("Added objects: {$this->runtimeStatistics->getAddedObjectCount()}, evictions: {$this->runtimeStatistics->getEvictedObjectCount()} ({$rateObjects} Obj/Sec, {$rateEvictions} Evi/Sec).");
         $this->runtimeStatistics->tick();
     });
 }
Example #11
0
 /**
  *
  */
 public function run()
 {
     $this->reactLoop->run();
 }
Example #12
0
 function loop()
 {
     $this->loop->run();
 }
Example #13
0
 /**
  *
  */
 public function stop()
 {
     $this->loop->stop();
 }
Example #14
0
 /**
  * @return Client
  */
 public function run() : Client
 {
     $this->loop->run();
     return $this;
 }
Example #15
0
 public function run()
 {
     $this->loop->run();
 }