public function __construct(Client $client, Mutex $mutex) { $this->client = $client; $this->mutex = $mutex; $this->locks = []; $this->repeatTimer = repeat(function () { foreach ($this->locks as $id => $token) { $this->mutex->renew($id, $token); } }, $this->mutex->getTTL() / 2); }
/** * @param string $root * @param \Amp\File\Driver $filesystem * @param \Amp\Reactor $reactor * @throws \DomainException On invalid root path */ public function __construct(string $root, file\Driver $filesystem = null) { $root = \str_replace("\\", "/", $root); if (!(\is_readable($root) && \is_dir($root))) { throw new \DomainException("Document root requires a readable directory"); } $this->root = \rtrim(\realpath($root), "/"); $this->filesystem = $filesystem ?: file\filesystem(); $this->multipartBoundary = \uniqid("", true); $this->cacheWatcher = amp\repeat(function () { $this->now = $now = time(); foreach ($this->cacheTimeouts as $path => $timeout) { if ($now <= $timeout) { break; } $fileInfo = $this->cache[$path]; unset($this->cache[$path], $this->cacheTimeouts[$path]); $this->bufferedFileCount -= isset($fileInfo->buffer); $this->cacheEntryCount--; } }, 1000, $options = ["enable" => false]); }
public function enableForRoom(Room $room, bool $persist = true) { repeat(function () use($room) { return $this->checkStatusChange($room); }, 150000); }
/** * Constructs a new Mutex instance. A single instance can be used to create as many locks as you need. * * @param string $uri URI of the Redis server instance, e.g. tcp://localhost:6379 * @param array $options { * General options for this instance. * * @type string|null $password password for the Redis server * @type int $max_connections maximum of concurrent Redis connections waiting for a lock with blocking commands * @type int timeout timeout for blocking lock wait * @type int $ttl key ttl for created locks and lock renews * } */ public function __construct(string $uri, array $options) { $this->uri = $uri; $this->options = $options; $this->std = new Client($uri, isset($options["password"]) ? ["password" => $options["password"]] : []); $this->maxConnections = $options["max_connections"] ?? 0; $this->ttl = $options["ttl"] ?? 1000; $this->timeout = (int) (($options["timeout"] ?? 1000) / 1000); $this->readyConnections = []; $this->busyConnections = []; $this->busyConnectionMap = []; $this->watcher = repeat(function () { $now = time(); $unused = $now - 60; foreach ($this->readyConnections as $key => list($time, $connection)) { if ($time > $unused) { break; } unset($this->readyConnections[$key]); $connection->close(); } }, 5000); }
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); }