mirror of
https://github.com/php-curl-class/php-curl-class.git
synced 2026-09-14 20:36:37 +00:00
Implement a more efficient handling of requests in parallel.
A window size is now used to set the maximum number of active requests at any given time. Each time a request is completed, a new request is added from the queue until all requests are processed. The result is a more continuous stream of requests rather than a burst of requests that may cause servers to quickly become overloaded.
This commit is contained in:
+1
-1
@@ -100,7 +100,7 @@ class Curl
|
||||
}
|
||||
|
||||
$this->curl = curl_init();
|
||||
$this->id = 1;
|
||||
$this->id = uniqid('', true);
|
||||
$this->setDefaultUserAgent();
|
||||
$this->setDefaultJsonDecoder();
|
||||
$this->setDefaultXmlDecoder();
|
||||
|
||||
+23
-13
@@ -6,8 +6,10 @@ class MultiCurl
|
||||
{
|
||||
public $baseUrl = null;
|
||||
public $multiCurl;
|
||||
public $curls = array();
|
||||
private $nextCurlId = 1;
|
||||
public $windowSize = 25;
|
||||
|
||||
private $curls = array();
|
||||
private $activeCurls = array();
|
||||
private $isStarted = false;
|
||||
|
||||
private $beforeSendFunction = null;
|
||||
@@ -524,8 +526,13 @@ class MultiCurl
|
||||
|
||||
$this->isStarted = true;
|
||||
|
||||
foreach ($this->curls as $ch) {
|
||||
$this->initHandle($ch);
|
||||
$window_size = $this->windowSize;
|
||||
if ($window_size > count($this->curls)) {
|
||||
$window_size = count($this->curls);
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $window_size; $i++) {
|
||||
$this->initHandle(array_pop($this->curls));
|
||||
}
|
||||
|
||||
do {
|
||||
@@ -534,15 +541,22 @@ class MultiCurl
|
||||
|
||||
while (!($info_array = curl_multi_info_read($this->multiCurl)) === false) {
|
||||
if ($info_array['msg'] === CURLMSG_DONE) {
|
||||
foreach ($this->curls as $key => $ch) {
|
||||
foreach ($this->activeCurls as $key => $ch) {
|
||||
if ($ch->curl === $info_array['handle']) {
|
||||
// Set the error code for multi handles using the "result" key in the array returned by
|
||||
// curl_multi_info_read(). Using curl_errno() on a multi handle will incorrectly return 0
|
||||
// for errors.
|
||||
$ch->curlErrorCode = $info_array['result'];
|
||||
$ch->exec($ch->curl);
|
||||
|
||||
unset($this->activeCurls[$key]);
|
||||
|
||||
// Start a new request before removing the handle of the completed one.
|
||||
if (count($this->curls) >= 1) {
|
||||
$this->initHandle(array_pop($this->curls));
|
||||
}
|
||||
curl_multi_remove_handle($this->multiCurl, $ch->curl);
|
||||
unset($this->curls[$key]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -550,7 +564,7 @@ class MultiCurl
|
||||
}
|
||||
|
||||
if (!$active) {
|
||||
$active = count($this->curls);
|
||||
$active = count($this->activeCurls);
|
||||
}
|
||||
} while ($active > 0);
|
||||
|
||||
@@ -616,12 +630,7 @@ class MultiCurl
|
||||
*/
|
||||
private function queueHandle($curl)
|
||||
{
|
||||
$curl->id = $this->nextCurlId++;
|
||||
$this->curls[] = $curl;
|
||||
|
||||
if ($this->isStarted) {
|
||||
$this->initHandle($curl);
|
||||
}
|
||||
$this->curls[$curl->id] = $curl;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -661,6 +670,7 @@ class MultiCurl
|
||||
throw new \ErrorException('cURL multi add handle error: ' . curl_multi_strerror($curlm_error_code));
|
||||
}
|
||||
|
||||
$this->activeCurls[$curl->id] = $curl;
|
||||
$curl->call($curl->beforeSendFunction);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user