Closed kelunik closed 7 years ago
Script used for reproduction:
<?php
use Amp\Loop;
use Amp\Artax\DefaultClient;
require_once __DIR__ . '/vendor/autoload.php';
error_reporting(-1);
print get_class(Loop::get()) . PHP_EOL;
$urlAsFile = function ($url, $timeout, $allowRedirects = false): \Amp\Promise {
$client = new DefaultClient();
$request = new \Amp\Artax\Request($url);
$totalTimeout = (int) (1000 * ($timeout));
$promise = $client->request($request, [
DefaultClient::OP_TRANSFER_TIMEOUT => $totalTimeout,
DefaultClient::OP_MAX_REDIRECTS => $allowRedirects ? 10 : 0,
]);
$deferred = new \Amp\Deferred();
$promise2 = $deferred->promise();
$promise->onResolve(function ($e, ?\Amp\Artax\Response $response) use ($deferred, $url) {
if ($e) {
$deferred->fail($e);
} else {
$tmpFile = 'foo.txt';
try {
while (($chunk = yield $response->getBody()->read()) !== null)
print "*";
print PHP_EOL;
$deferred->resolve($tmpFile);
} catch (\Throwable $e) {
$deferred->fail($e);
}
}
});
return $promise2;
};
while (true) {
Loop::set((new Amp\Loop\DriverFactory)->create());
try {
Amp\Promise\wait(Amp\call(function () use ($urlAsFile) {
$start = microtime(true);
$f = yield $urlAsFile('https://i.jaumo.com/go/2651,766d972eda9dc4d0.jpg', 3);
$end = microtime(true);
$time = ($end - $start) * 1000;
# echo $i . "= " . filesize($f) . " " . sprintf("%0.3f", $time) . "ms\n";
echo ".";
}));
} catch (\Error $e) {
var_dump(Loop::getInfo());
throw $e;
}
}
Usually takes quite some requests to get triggered. It's driver independent.
Ok, I know why. People using multiple event loops deserve what they get from PHP's __destruct
. Will post a PR to amphp/amp
soon.
Closing as amphp/amp#171 got merged.
In certain edge cases the loop stops without resolving the promise returned from
BasicResolver::resolve()
. Reproducible with the script from https://github.com/amphp/artax/issues/138 with a fix for the TLS hanging.