private function connect(Request $request) { $promise = httpClient()->request($request, [HttpClient::OP_DISCARD_BODY => true, HttpClient::OP_MS_TRANSFER_TIMEOUT => null]); // yes, yes not spec compliant but it *gets the job done* until we can implement something better $chunkCombiner = new JsonChunkCombiner(); $stats = new Stats(); $logger = $this->logger; $callback = function (array $notifyData) use($chunkCombiner, $stats, $logger) { $event = array_shift($notifyData); if ($event === Notify::REQUEST_SENT) { $stats->increment('connectionAttempts'); $msg = "Connection request #{$stats->connectionAttempts()} sent"; $logger->info($msg); } if ($event === Notify::RESPONSE_HEADERS) { $stats->streamEstablished(); $prettyTime = date('Y-m-d H:i:s', $stats->startTime()); $logger->info("Twitter responded at {$prettyTime} UTC"); } if ($event === Notify::RESPONSE_BODY_DATA) { $data = trim($notifyData[0]); if (!empty($data)) { $chunkCombiner->push($data); if ($chunkCombiner->isValidJson()) { // TODO pass $json to Storage when implemented $json = $chunkCombiner->getCombinedChunksAsJson(); $chunkCombiner->clearChunks(); $stats->increment('statusUpdates'); } } } }; $promise->watch($callback); $promise->when(function ($err, $response) use($logger) { if ($err) { $exceptionType = get_class($err); $msg = "{$exceptionType}('{$err->getMessage()}') in {$err->getFile()} on L{$err->getLine()}"; $logger->critical($msg); // TODO if an exception was thrown should decide if we want to stop execution; this should probably not happen in normal circumstances } else { $msg = "Connection ended: {$response->getStatus()} {$response->getReason()}"; $logger->error($msg); } // TODO remove this when we have the reconnection/backoff implemented \Amp\stop(); }); $statUpdate = function () use($stats) { $runningTime = time() - $stats->startTime(); $this->logger->info("Stats: {$stats->statusUpdates()} statuses. Running for {$runningTime} seconds."); }; $statUpdate = $statUpdate->bindTo($this, $this); repeat($statUpdate, 15000); }
private function addSignals() { \Amp\onSignal(SIGINT, function () { exit; }); \Amp\onSignal(SIGTERM, function () { exit; }); register_shutdown_function(function () { $this->logger->alert('Clean exit. Thank you.'); if (\Amp\info()["state"] !== \Amp\Reactor::STOPPED) { \Amp\stop(); } }); return true; }
<?php declare (strict_types=1); namespace Amplify; use Aerys\Request; use Aerys\Response; use function Aerys\router; use function Aerys\websocket; $router = router()->route('GET', '/', function (Request $request, Response $response) use($template) { $response->send(file_get_contents(__DIR__ . '/templates/page.phtml')); })->route('GET', '/ws', websocket(new Handler(), ["maxBytesPerMinute" => 1 << 26, "maxFramesPerSecond" => 1000000]))->route('GET', '/stop', function () { \Amp\stop(); });
public function stop() { \Amp\stop(); }
public function testGetStats() { \Amp\run(function () { $stats = (yield $this->memcached->getStats()); $this->assertInternalType('array', $stats); $this->assertArrayHasKey('pid', $stats); \Amp\stop(); }); }