protected function connectSocket(Uri $uri) : Awaitable { $host = $uri->getHost(); if (Address::isResolved($host)) { $factory = new SocketFactory(new Address($host) . ':' . $uri->getPort(), 'tcp'); } else { $factory = new SocketFactory($uri->getHostWithPort(true), 'tcp'); } $factory->setTcpNoDelay(true); if ($this->protocols && Socket::isAlpnSupported()) { $factory->setOption('ssl', 'alpn_protocols', \implode(',', $this->protocols)); } return $factory->createSocketStream(5, $uri->getScheme() === 'https'); }
public function releaseConnection(Uri $uri, ConnectorContext $context, int $ttl = null, int $remaining = null) { $key = \sprintf('%s://%s', $uri->getScheme(), $uri->getHostWithPort(true)); if ($ttl === null) { $ttl = $this->maxLifetime; } else { $ttl = \min($ttl, $this->maxLifetime); } if ($remaining === null) { $remaining = $this->max; } else { $remaining = \min($remaining, $this->max); } if ($remaining > 0 && $ttl > 0 && $context->socket->isAlive()) { $context->connected = true; if (empty($this->conns[$key])) { $this->conns[$key] = new \SplQueue(); } if (!empty($this->connecting[$key])) { $defer = \array_shift($this->connecting[$key]); return $defer->resolve($context); } $context->expires = \time() + $ttl; $context->remaining = $remaining; $this->conns[$key]->enqueue($context); return; } $context->socket->close(); $this->connectionDisposed($key); }
/** * {@inheritdoc} */ public function getConnectorContext(Uri $uri) : Awaitable { $key = \sprintf('%s://%s', $uri->getScheme(), $uri->getHostWithPort(true)); if (isset($this->connections[$key])) { if ($this->connections[$key]->isAlive()) { $context = new ConnectorContext(); $context->connected = true; $context->conn = $this->connections[$key]; return new Success($context); } unset($this->connections[$key]); } if (isset($this->connecting[$key])) { $defer = new Deferred(); $this->connecting[$key]->enqueue($defer); return $defer; } $this->connecting[$key] = new \SplQueue(); $context = new ConnectorContext(function ($context) use($key) { if ($this->connecting[$key]->isEmpty()) { unset($this->connecting[$key]); } else { $this->connecting[$key]->dequeue()->resolve($context); } }); return new Success($context); }