private function onDeadIpcSock() { $this->isDead = true; $this->writeBuffer = ""; $this->writeQueue = []; \Amp\cancel($this->writeWatcherId); }
private function succeed() { $this->promisor->succeed(); if ($this->writeWatcher) { \Amp\cancel($this->writeWatcher); } }
protected function doStart(Console $console) : \Generator { $server = $this->bootstrapper->boot($this->logger, $console); (yield $server->start()); $this->server = $server; \Amp\onReadable($this->ipcSock, function ($watcherId) { \Amp\cancel($watcherId); yield from $this->stop(); }); }
private function onDeadIpcSock() { $this->isDead = true; $this->writeBuffer = ""; $this->writeQueue = []; \Amp\cancel($this->writeWatcherId); if ($this->stopPromisor) { $promisor = $this->stopPromisor; $this->stopPromisor = null; $promisor->succeed(); } }
private function failAll() { if ($this->writeWatcher !== null) { \Amp\cancel($this->writeWatcher); } $this->sock = $this->writeWatcher = null; $promisors = $this->promisors; $this->promisors = []; foreach ($promisors as $deferred) { $deferred->fail(new \Exception("Couldn't write command, server failed.")); } }
public final function update(\SplSubject $subject) : Promise { switch ($subject->state()) { case Server::STARTED: $this->watcherId = \Amp\repeat([$this, "updateTime"], 1000); $this->updateTime(); break; case Server::STOPPED: \Amp\cancel($this->watcherId); $this->watcherId = null; break; } return new Success(); }
protected function doStart(Console $console) : \Generator { // Shutdown the whole server in case we needed to stop during startup register_shutdown_function(function () use($console) { if (!$this->server) { // ensure a clean reactor for clean shutdown $reactor = \Amp\reactor(); \Amp\reactor(\Amp\driver()); \Amp\wait((new CommandClient((string) $console->getArg("config")))->stop()); \Amp\reactor($reactor); } }); $server = (yield from $this->bootstrapper->boot($this->logger, $console)); (yield $server->start()); $this->server = $server; \Amp\onReadable($this->ipcSock, function ($watcherId) { \Amp\cancel($watcherId); yield from $this->stop(); }); }
public function __destruct() { $this->stream = null; \Amp\cancel($this->watcher); /** * pecl/eio has a race condition issue when freeing threaded * resources and we can get intermittent segfaults at script * shutdown in certain cases if we don't wait for a moment. * * @TODO see if we can PR a fix for this problem in pecl/eio */ usleep(1000); }
public function cancel($signal = 9) { if (!$this->proc) { return; } \Amp\cancel($this->stdout); \Amp\cancel($this->stderr); \Amp\cancel($this->stdin); if (isset($this->exit)) { \Amp\cancel($this->exit); } $deferreds = $this->writeDeferreds; $this->writeDeferreds = []; $this->kill($signal); unset($this->proc); $this->deferred->fail(new \RuntimeException("Process watching was cancelled")); foreach ($deferreds as $deferred) { $deferred->fail(new \Exception("Write could not be completed, process watching was cancelled")); } }
private function parseSocketData(HttpTunnelStruct $struct, $data) { try { $struct->parser->buffer($data); if (!($parsedResponseArr = $struct->parser->parse())) { return; } $status = $parsedResponseArr['status']; if ($status == 200) { // Tunnel connected! We're finished \o/ #WinningAtLife #DealWithIt stream_context_set_option($struct->socket, 'artax*', 'is_tunneled', true); $struct->promisor->succeed($struct->socket); \Amp\cancel($struct->readWatcher); } else { $struct->promisor->fail(new ClientException(sprintf('Unexpected response status received from proxy: %d', $status))); \Amp\cancel($struct->readWatcher); } } catch (ParseException $e) { \Amp\cancel($struct->readWatcher); $struct->promisor->fail(new ClientException('Invalid HTTP response received from proxy while establishing tunnel', 0, $e)); } }
public function __destruct() { $this->sharedState->cache = []; $this->sharedState->cacheTimeouts = []; \Amp\cancel($this->ttlWatcherId); }
private function clear(Client $client) { $client->requestParser = null; $client->onWriteDrain = null; \Amp\cancel($client->readWatcher); \Amp\cancel($client->writeWatcher); $this->clearKeepAliveTimeout($client); unset($this->clients[$client->id]); if ($this->stopPromisor && empty($this->clients)) { $this->stopPromisor->succeed(); } }
public function send($socket) { $deferred = new Deferred(); stream_set_blocking($socket, false); $data = $this->getRequest(); \Amp\onWritable($socket, function ($writer, $socket) use($deferred, &$data) { if ($bytes = fwrite($socket, $data)) { if ($bytes < \strlen($data)) { $data = substr($data, $bytes); return; } $size = 8192; \Amp\onReadable($socket, function ($reader, $socket) use($deferred, &$size) { /* make attention to not read too much data */ $data = stream_socket_recvfrom($socket, $size, STREAM_PEEK); if (false === ($pos = strpos($data, "\r\n\r\n"))) { if (\strlen($data) == $size) { $size *= 2; // unbounded?? } return; } \Amp\cancel($reader); $deferred->succeed($this->parseResponse(fread($socket, $pos + 4))); }); } else { $deferred->succeed(null); } \Amp\cancel($writer); }); return $deferred->promise(); }
private function proceedFrom100ContinueState(RequestCycle $cycle) { $continueWatcher = $cycle->continueWatcher; $cycle->continueWatcher = null; \Amp\cancel($continueWatcher); $this->writeBody($cycle); }
public function __destruct() { \Amp\cancel($this->watcher); }
public function update(Server $server) : Promise { switch ($this->state = $server->state()) { case Server::STARTING: $result = $this->application->onStart($this->proxy); if ($result instanceof \Generator) { return resolve($result); } break; case Server::STARTED: $f = (new \ReflectionClass($this))->getMethod("timeout")->getClosure($this); $this->timeoutWatcher = \Amp\repeat($f, 1000); break; case Server::STOPPING: $result = $this->application->onStop(); if ($result instanceof \Generator) { $promise = resolve($result); } elseif ($result instanceof Promise) { $promise = $result; } else { $promise = new Success(); } $promise->when(function () { $code = Code::GOING_AWAY; $reason = "Server shutting down!"; foreach ($this->clients as $client) { $this->close($client->id, $code, $reason); } }); \Amp\cancel($this->timeoutWatcher); $this->timeoutWatcher = null; return $promise; case Server::STOPPED: $promises = []; // we are not going to wait for a proper self::OP_CLOSE answer (because else we'd need to timeout for 3 seconds, not worth it), but we will ensure to at least *have written* it foreach ($this->clients as $client) { // only if we couldn't successfully send it in STOPPING $code = Code::GOING_AWAY; $reason = "Server shutting down!"; $result = $this->doClose($client, $code, $reason); if ($result instanceof \Generator) { $promise[] = resolve($result); } if (!empty($client->writeDeferredControlQueue)) { $promise = end($client->writeDeferredControlQueue)->promise(); if ($promise) { $promises[] = $promise; } } } $promise = any($promises); $promise->when(function () { foreach ($this->clients as $client) { $this->unloadClient($client); } }); return $promise; } return new Success(); }
public static function reader($watcher, $socket, $info) { $buffer =& $info[0]; $data = @fread($socket, 8192); if ($data != "") { if ($buffer == "") { \Amp\enable($info[1]); } $buffer .= $data; if (\strlen($buffer) > self::MAX_INTERMEDIARY_BUFFER) { \Amp\disable($watcher); } } elseif (!is_resource($socket) || @feof($socket)) { \Amp\cancel($watcher); if ($buffer == "") { \Amp\cancel($info[1]); } else { $info[2] = true; } } }
function __onCryptoWatchReadability($watcherId, $socket, $cbData) { list($promisor, $method) = $cbData; $result = \stream_socket_enable_crypto($socket, $enable = true, $method); if ($result === true) { \Amp\cancel($watcherId); $promisor->succeed($socket); } elseif ($result === false) { \Amp\cancel($watcherId); $promisor->fail(new CryptoException("Crypto negotiation failed: " . (feof($socket) ? "Connection reset by peer" : \error_get_last()["message"]))); } }
private function unloadSocket($uri, $socketId) { if (!isset($this->sockets[$uri][$socketId])) { return; } $poolStruct = $this->sockets[$uri][$socketId]; if ($poolStruct->idleWatcher) { \Amp\cancel($poolStruct->idleWatcher); } unset($this->sockets[$uri][$socketId], $this->socketIdUriMap[$socketId]); if (empty($this->sockets[$uri])) { unset($this->sockets[$uri][$socketId]); } if (!empty($this->queuedSocketRequests[$uri])) { $this->dequeueNextWaitingSocket($uri); } }
function __unloadServer($state, $serverId, $error = null) { $server = $state->serverIdMap[$serverId]; \Amp\cancel($server->watcherId); unset($state->serverIdMap[$serverId], $state->serverUriMap[$server->uri]); if (\is_resource($server->socket)) { @\fclose($server->socket); } if ($error && $server->pendingRequests) { foreach (array_keys($server->pendingRequests) as $requestId) { list($promisor) = $state->pendingRequests[$requestId]; $promisor->fail($error); } } }
private function unloadServer($serverId, $error = null) { // Might already have been unloaded (especially if multiple requests happen) if (!isset($this->serverIdMap[$serverId])) { return; } $server = $this->serverIdMap[$serverId]; \Amp\cancel($server->watcherId); unset($this->serverIdMap[$serverId], $this->serverUriMap[$server->uri]); if (\is_resource($server->socket)) { @\fclose($server->socket); } if ($error && $server->pendingRequests) { foreach (array_keys($server->pendingRequests) as $requestId) { list($promisor) = $this->pendingRequests[$requestId]; $promisor->fail($error); } } }
private function onDeadIpcClient(string $readWatcherId, $ipcClient) { \Amp\cancel($readWatcherId); @fclose($ipcClient); unset($this->ipcClients[$readWatcherId]); $this->defunctProcessCount++; \Amp\enable($this->procGarbageWatcher); }
public function send($socket) { $deferred = new Deferred(); stream_set_blocking($socket, false); $data = $this->getRequest(); \Amp\onWritable($socket, function ($writer, $socket) use($deferred, &$data) { if ($bytes = fwrite($socket, $data)) { if ($bytes < \strlen($data)) { $data = substr($data, $bytes); return; } $data = ''; \Amp\onReadable($socket, function ($reader, $socket) use($deferred, &$data) { $data .= $bytes = fgets($socket); if ($bytes == '' || \strlen($bytes) > 32768) { \Amp\cancel($reader); $deferred->succeed(null); } elseif (substr($data, -4) == "\r\n\r\n") { \Amp\cancel($reader); $deferred->succeed($this->parseResponse($data)); } }); } else { $deferred->succeed(null); } \Amp\cancel($writer); }); return $deferred->promise(); }