Skip to content

Commit

Permalink
Improve HTTP/2 flow control parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
kelunik committed Dec 2, 2019
1 parent 727126d commit 1a89ba3
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 16 deletions.
79 changes: 79 additions & 0 deletions examples/streaming/2-http1-http2.php
@@ -0,0 +1,79 @@
<?php


use Amp\File\File;
use Amp\File\StatCache;
use Amp\Http\Client\HttpClientBuilder;
use Amp\Http\Client\HttpException;
use Amp\Http\Client\Request;
use Amp\Http\Client\Response;
use Amp\Loop;
use function Amp\getCurrentTime;

require __DIR__ . '/../.helper/functions.php';

// https://stackoverflow.com/a/2510540/2373138
function formatBytes(int $size, int $precision = 2)
{
$base = \log($size, 1024);
$suffixes = ['bytes', 'kB', 'MB', 'GB', 'TB'];

return \round(1024 ** ($base - \floor($base)), $precision) . ' ' . $suffixes[(int) $base];
}

function fetch(string $uri, array $protocolVersions): \Generator
{
try {
$start = getCurrentTime();

// Instantiate the HTTP client
$client = HttpClientBuilder::buildDefault();

$request = new Request($uri);
$request->setProtocolVersions($protocolVersions);
$request->setBodySizeLimit(16 * 1024 * 1024); // 128 MB
$request->setTransferTimeout(120 * 1000); // 120 seconds

/** @var Response $response */
$response = yield $client->request($request);

print "\n";

$path = \tempnam(\sys_get_temp_dir(), "artax-streaming-");

/** @var File $file */
$file = yield Amp\File\open($path, "w");

$bytes = 0;

while (null !== $chunk = yield $response->getBody()->read()) {
yield $file->write($chunk);
$bytes += \strlen($chunk);

print "\r" . formatBytes($bytes) . ' '; // blanks to remove previous output
}

yield $file->close();

print \sprintf(
"\rDone in %.2f seconds with peak memory usage of %.2fMB.\n",
(getCurrentTime() - $start) / 1000,
(float) \memory_get_peak_usage(true) / 1024 / 1024
);

// We need to clear the stat cache, as we have just written to the file
StatCache::clear($path);
$size = yield Amp\File\size($path);

print \sprintf("%s has a size of %.2fMB\r\n", $path, (float) $size / 1024 / 1024);
} catch (HttpException $error) {
// If something goes wrong Amp will throw the exception where the promise was yielded.
// The HttpClient::request() method itself will never throw directly, but returns a promise.
echo $error;
}
}

Loop::run(static function () {
yield from fetch('http://1153288396.rsc.cdn77.org//img/cdn77-test-14mb.jpg', ['1.1']);
yield from fetch('https://1906714720.rsc.cdn77.org/img/cdn77-test-14mb.jpg', ['2']);
});
30 changes: 14 additions & 16 deletions src/Connection/Internal/Http2ConnectionProcessor.php
Expand Up @@ -42,8 +42,8 @@ final class Http2ConnectionProcessor implements Http2Processor
private const DEFAULT_MAX_FRAME_SIZE = 1 << 14;
private const DEFAULT_WINDOW_SIZE = (1 << 16) - 1;

private const MINIMUM_WINDOW = (1 << 15) - 1;
private const MAX_INCREMENT = (1 << 16) - 1;
private const MINIMUM_WINDOW = 128 * 1024;
private const WINDOW_INCREMENT = 128 * 1024;

// Milliseconds to wait for pong (PING with ACK) frame before closing the connection.
private const PONG_TIMEOUT = 500;
Expand Down Expand Up @@ -448,15 +448,14 @@ public function handleHeaders(int $streamId, array $pseudo, array $headers): voi
return $response;
}));

if ($this->serverWindow <= self::MINIMUM_WINDOW) {
$this->serverWindow += self::MAX_INCREMENT;
$this->writeFrame(self::WINDOW_UPDATE, 0, 0, \pack("N", self::MAX_INCREMENT));
while ($this->serverWindow <= self::MINIMUM_WINDOW) {
$this->serverWindow += self::WINDOW_INCREMENT;
$this->writeFrame(self::WINDOW_UPDATE, 0, 0, \pack("N", self::WINDOW_INCREMENT));
}

if ($stream->serverWindow <= self::MINIMUM_WINDOW) {
$stream->serverWindow += self::MAX_INCREMENT;

$this->writeFrame(self::WINDOW_UPDATE, self::NO_FLAG, $streamId, \pack("N", self::MAX_INCREMENT));
while ($stream->serverWindow <= self::MINIMUM_WINDOW) {
$stream->serverWindow += self::WINDOW_INCREMENT;
$this->writeFrame(self::WINDOW_UPDATE, self::NO_FLAG, $streamId, \pack("N", self::WINDOW_INCREMENT));
}

if (isset($headers["content-length"])) {
Expand Down Expand Up @@ -739,9 +738,9 @@ public function handleData(int $streamId, string $data): void
return;
}

if ($this->serverWindow <= self::MINIMUM_WINDOW) {
$this->serverWindow += self::MAX_INCREMENT;
$this->writeFrame(self::WINDOW_UPDATE, 0, 0, \pack("N", self::MAX_INCREMENT));
while ($this->serverWindow <= self::MINIMUM_WINDOW) {
$this->serverWindow += self::WINDOW_INCREMENT;
$this->writeFrame(self::WINDOW_UPDATE, 0, 0, \pack("N", self::WINDOW_INCREMENT));
}

$promise = $stream->body->emit($data);
Expand All @@ -753,10 +752,9 @@ public function handleData(int $streamId, string $data): void

$stream = $this->streams[$streamId];

if ($stream->serverWindow <= self::MINIMUM_WINDOW) {
$stream->serverWindow += self::MAX_INCREMENT;

$this->writeFrame(self::WINDOW_UPDATE, self::NO_FLAG, $streamId, \pack("N", self::MAX_INCREMENT));
while ($stream->serverWindow <= self::MINIMUM_WINDOW) {
$stream->serverWindow += self::WINDOW_INCREMENT;
$this->writeFrame(self::WINDOW_UPDATE, self::NO_FLAG, $streamId, \pack("N", self::WINDOW_INCREMENT));
}
});
}
Expand Down

0 comments on commit 1a89ba3

Please sign in to comment.