Skip to content

Commit

Permalink
Tighten keep-alive timeout and use pings in HTTP/2
Browse files Browse the repository at this point in the history
Hopefully these changes will make connection reuse a little safer.
  • Loading branch information
trowski committed Sep 27, 2019
1 parent 5162274 commit 12426f5
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/Connection/Http1Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ private function determineKeepAliveTimeout(Response $response): int
$params = Http\createFieldValueComponentMap(Http\parseFieldValueComponents($response, 'keep-alive'));

return $this->priorTimeout = \min(
\max(0, $params['timeout'] ?? $this->priorTimeout),
\max(0, ((int) ($params['timeout'] ?? $this->priorTimeout)) - 1),
self::MAX_KEEP_ALIVE_TIMEOUT
);
}
Expand Down
36 changes: 36 additions & 0 deletions src/Connection/Http2Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ final class Http2Connection implements Connection
public const DEFAULT_MAX_HEADER_SIZE = 1 << 20;
public const DEFAULT_MAX_BODY_SIZE = 1 << 30;

private const PING_INTERVAL = 5 * 1000; // Ping interval in milliseconds.
private const IDLE_PING_COUNT = 2; // Number of idle pings to send before closing the connection.

/** @var string 64-bit for ping. */
private $counter = "aaaaaaaa";

/** @var Socket */
private $socket;

Expand Down Expand Up @@ -150,6 +156,12 @@ final class Http2Connection implements Connection
/** @var bool */
private $initialized = false;

/** @var int */
private $pingCount = 0;

/** @var string */
private $pingWatcher;

public function __construct(Socket $socket)
{
$this->table = new HPack;
Expand All @@ -159,6 +171,16 @@ public function __construct(Socket $socket)
if ($this->socket->isClosed()) {
$this->onClose = null;
}

$this->pingWatcher = Loop::repeat(self::PING_INTERVAL, function (): void {
if (++$this->pingCount > self::IDLE_PING_COUNT) {

This comment has been minimized.

Copy link
@kelunik

kelunik Sep 27, 2019

Member

Shouldn't the ping count reduced somewhere?

$this->close();
return;
}

$this->ping();
});
Loop::unreference($this->pingWatcher);
}

/**
Expand Down Expand Up @@ -213,6 +235,10 @@ public function getStream(Request $request): Stream

private function request(Request $request, CancellationToken $token): Promise
{
$this->pingCount = 0;

Loop::disable($this->pingWatcher);

$request = clone $request;

// Remove defunct HTTP/1.x headers.
Expand Down Expand Up @@ -307,6 +333,7 @@ private function request(Request $request, CancellationToken $token): Promise
}

if ($chunk === null) {
Loop::enable($this->pingWatcher);
return yield $deferred->promise();
}

Expand All @@ -328,6 +355,8 @@ private function request(Request $request, CancellationToken $token): Promise

yield $this->writeData($buffer, $id);

Loop::enable($this->pingWatcher);

return yield $deferred->promise();
} catch (\Throwable $exception) {
if (isset($this->streams[$id])) {
Expand All @@ -340,6 +369,11 @@ private function request(Request $request, CancellationToken $token): Promise
});
}

public function ping(): Promise
{
return $this->writeFrame($this->counter++, self::PING, self::NOFLAG);
}

private function release(): void
{
++$this->remainingStreams;
Expand Down Expand Up @@ -1337,6 +1371,8 @@ private function shutdown(?int $lastId = null, ?\Throwable $reason = null): Prom
}
}

Loop::cancel($this->pingWatcher);

return $promise;
}

Expand Down

0 comments on commit 12426f5

Please sign in to comment.