Easy to reproduce with current stable version (0.7.0) and this code (to fix it - just add socket clearing in doError() function):
<?php
require(__DIR__ . '/vendor/autoload.php');
$reactor = (new Alert\ReactorFactory)->select();
$client = new Artax\AsyncClient($reactor);
$client->setOption('maxconnections', 5);
$client->setOption('connecttimeout', 1);
// Generate a request URI for each letter a-z
$requests = array_map(function($alpha) { return 'http://8.8.8.8/search?q=' . $alpha; }, range('a', 'z'));
// We need to track how many requests remain so we can stop the program when they're all finished
$unfinishedRequests = count($requests);
// What to do when an individual request completes
$onResponse = function(Artax\Response $response, Artax\Request $request) use (&$unfinishedRequests, $reactor) {
echo $request->getUri(), ' -- ';
echo 'HTTP/', $response->getProtocol(), ' ', $response->getStatus(), ' ', $response->getReason(), "\n";
echo $unfinishedRequests, PHP_EOL;
if (!--$unfinishedRequests) {
$reactor->stop();
}
};
// What to do if a request encounters an exceptional error
$onError = function(Exception $e, Artax\Request $request) use (&$unfinishedRequests, $reactor) {
echo $request->getUri(), " failed (", get_class($e), ") :(\n";
echo $unfinishedRequests, PHP_EOL;
if (!--$unfinishedRequests) {
$reactor->stop();
}
};
// The reactor IS our task scheduler and the program runs inside it. Nothing will happen until the
// event reactor is started, so release the hounds!
$reactor->run(function() use ($client, $requests, $onResponse, $onError) {
echo 'Requesting ', count($requests), ' URIs ...', "\n";
foreach ($requests as $uri) {
$client->request($uri, $onResponse, $onError);
}
});
And another issue on current master branch - script just terminates after 5th failure.