Skip to content

Commit 0976581

Browse files
authored
实现重试回调 (#24)
1 parent fc11816 commit 0976581

4 files changed

Lines changed: 51 additions & 12 deletions

File tree

src/HttpRequest.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ class HttpRequest
5858
*/
5959
public $retry = 0;
6060

61+
/**
62+
* 重试回调.
63+
*
64+
* @var callable|null
65+
*/
66+
public $retryCallback = null;
67+
6168
/**
6269
* 是否使用代理,默认false.
6370
*
@@ -267,6 +274,7 @@ public function open($options = [])
267274
{
268275
$this->handler = YurunHttp::getHandler($options);
269276
$this->retry = 0;
277+
$this->retryCallback = null;
270278
$this->headers = $this->options = [];
271279
$this->url = $this->content = '';
272280
$this->useProxy = false;
@@ -639,13 +647,15 @@ public function ua($userAgent)
639647
/**
640648
* 设置失败重试次数,状态码为5XX或者0才需要重试.
641649
*
642-
* @param string $retry
650+
* @param int $retry
651+
* @param callable|null $callback
643652
*
644653
* @return static
645654
*/
646-
public function retry($retry)
655+
public function retry($retry, $callback = null)
647656
{
648657
$this->retry = $retry < 0 ? 0 : $retry; //至少请求1次,即重试0次
658+
$this->retryCallback = $callback;
649659

650660
return $this;
651661
}
@@ -938,6 +948,8 @@ public function buildRequest($url = null, $requestBody = null, $method = null, $
938948
->withAttribute(Attributes::UPLOAD_SPEED, $this->uploadSpeed)
939949
->withAttribute(Attributes::FOLLOW_LOCATION, $this->followLocation)
940950
->withAttribute(Attributes::CONNECTION_POOL, $this->connectionPool)
951+
->withAttribute(Attributes::RETRY, $this->retry)
952+
->withAttribute(Attributes::RETRY_CALLBACK, $this->retryCallback)
941953
->withProtocolVersion($this->protocolVersion)
942954
;
943955
foreach ($this->proxy as $name => $value)

src/YurunHttp/Attributes.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ abstract class Attributes
2424
*/
2525
const RETRY = 'retry';
2626

27+
/**
28+
* 重试回调.
29+
*/
30+
const RETRY_CALLBACK = 'retry_callback';
31+
2732
/**
2833
* 下载文件保存路径.
2934
*/

src/YurunHttp/Handler/Curl.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ public function send(&$request)
180180
$isLocation = false;
181181
$statusCode = 0;
182182
$redirectCount = 0;
183+
$retry = $request->getAttribute(Attributes::RETRY, 0);
184+
$retryCallback = $request->getAttribute(Attributes::RETRY_CALLBACK);
183185
$beginTime = microtime(true);
184186
do
185187
{
@@ -201,19 +203,28 @@ public function send(&$request)
201203
$bodyContent = false;
202204
}
203205
$this->buildCurlHandlerEx($request, $handler, $uri, $method, $bodyContent);
204-
$retry = $request->getAttribute(Attributes::RETRY, 0);
205206
$result = null;
206207
for ($i = 0; $i <= $retry; ++$i)
207208
{
208209
$receiveHeaders = [];
209210
$curlResult = curl_exec($handler);
210211
$this->result = $this->getResponse($request, $handler, $curlResult, $receiveHeaders);
211212
$result = &$this->result;
212-
$statusCode = $result->getStatusCode();
213-
// 状态码为5XX或者0才需要重试
214-
if (!(0 === $statusCode || (5 === (int) ($statusCode / 100))))
213+
if ($retryCallback)
215214
{
216-
break;
215+
if ($retryCallback($request, $result, $i))
216+
{
217+
break;
218+
}
219+
}
220+
else
221+
{
222+
$statusCode = $result->getStatusCode();
223+
// 状态码为5XX或者0才需要重试
224+
if (!(0 === $statusCode || (5 === (int) ($statusCode / 100))))
225+
{
226+
break;
227+
}
217228
}
218229
}
219230
if ($request->getAttribute(Attributes::FOLLOW_LOCATION, true) && ($statusCode >= 300 && $statusCode < 400) && $result && '' !== ($location = $result->getHeaderLine('location')))

src/YurunHttp/Handler/Swoole.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -407,13 +407,24 @@ public function recvDefer($request, $timeout = null)
407407
}
408408
$result = &$this->result;
409409
$statusCode = $result->getStatusCode();
410-
// 状态码为5XX或者0才需要重试
411-
if ((0 === $statusCode || (5 === (int) ($statusCode / 100))) && $retryCount < $request->getAttribute(Attributes::RETRY, 0))
410+
if ($retryCount < $request->getAttribute(Attributes::RETRY, 0))
412411
{
413-
$request = $request->withAttribute(Attributes::RETRY, ++$retryCount);
414-
$deferRequest = $this->sendDefer($request);
412+
if ($retryCallback = $request->getAttribute(Attributes::RETRY_CALLBACK))
413+
{
414+
$retry = !$retryCallback($request, $result, $retryCount);
415+
}
416+
else
417+
{
418+
// 状态码为5XX或者0才需要重试
419+
$retry = (0 === $statusCode || (5 === (int) ($statusCode / 100)));
420+
}
421+
if ($retry)
422+
{
423+
$request = $request->withAttribute(Attributes::PRIVATE_RETRY_COUNT, ++$retryCount);
424+
$deferRequest = $this->sendDefer($request);
415425

416-
return $this->recvDefer($deferRequest, $timeout);
426+
return $this->recvDefer($deferRequest, $timeout);
427+
}
417428
}
418429
if (!$isWebSocket && $statusCode >= 300 && $statusCode < 400 && $request->getAttribute(Attributes::FOLLOW_LOCATION, true) && '' !== ($location = $result->getHeaderLine('location')))
419430
{

0 commit comments

Comments
 (0)