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; }); }
/** * 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(); }
/** * 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(); }
public function bye() { if ($this->connection->isWritable()) { $this->connection->write(json_encode(array('cmd' => 'unregister', 'pid' => getmypid()))); $this->connection->close(); } $this->loop->stop(); }
private function setTimer() { $this->loop->addPeriodicTimer(1, function () { if ($this->getBridge() instanceof Bridges\TimerBridgeInterface) { $this->getBridge()->timer($this); } }); }
/** * Construct. */ public function __construct() { parent::__construct(); $class = new \ReflectionClass('\\React\\EventLoop\\LibEventLoop'); $property = $class->getProperty('eventBase'); $property->setAccessible(true); $this->_eventBase = $property->getValue($this); }
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; }
/** * 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); }); }
/** * 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(); }
/** * 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(); }); }
/** * */ public function run() { $this->reactLoop->run(); }
function loop() { $this->loop->run(); }
/** * */ public function stop() { $this->loop->stop(); }
/** * @return Client */ public function run() : Client { $this->loop->run(); return $this; }
public function run() { $this->loop->run(); }