Skip to content

Commit

Permalink
Update retry handler, Fix swlib#19, add retry tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
twose committed Nov 28, 2018
1 parent f3400a6 commit 5cd1134
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 19 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ go(function () {
- <a href="#swlibsaberwebsocket">Swlib\Saber\WebSocket</a>
- <a href="#swlibsaberwebsocketframe">Swlib\Saber\WebSocketFrame</a>


------

## 例子
Expand Down Expand Up @@ -284,14 +283,20 @@ if ($response->success) {

`Saber`内置了此功能, 并可使用`拦截器`来强化它.

如未设置`retry_time`而设置了`retry`拦截器, 则`retry_time`会置为1, 如`retry`拦截器的回调方法返回了`false`, 无论`retry_time`是多少, 都会在返回`false`时终止重试.

```PHP
$uri = 'http://eu.httpbin.org/basic-auth/foo/bar';
$res = SaberGM::get(
$uri, [
'exception_report' => 0,
'retry_time' => 3,
'retry' => function (Saber\Request $request) {
echo "retry...\n";
$request->withBasicAuth('foo', 'bar'); //发现失败后添加验证信息
if ('i don not want to retry again') {
return false; // shutdown
}
}
]
);
Expand Down
53 changes: 35 additions & 18 deletions src/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,16 @@

class Request extends \Swlib\Http\Request
{
public const STATUS_NONE = 1;
public const STATUS_WAITING = 2;

protected const FROM_REDIRECT = 1 << 1;
protected const FROM_RETRY = 1 << 2;

/** @var $client \Swoole\Coroutine\Http\Client */
public $client;
/** @var bool must be changed through method */
private $use_pool = false;
protected $use_pool = false;

public $exception_report = HttpExceptionMask::E_ALL;

Expand Down Expand Up @@ -51,14 +57,16 @@ class Request extends \Swlib\Http\Request
public $retry_time = 0;

/** @var string where download to */
private $download_dir = '';
private $download_offset = 0;
protected $download_dir = '';
protected $download_offset = 0;

public $auto_iconv = true;
public $charset_source;
public $charset_target;
public $charset_use_mb = false;

/** @var int client status */
public $_status = self::STATUS_NONE;
/** @var float request start micro time */
public $_start_time;
/** @var float timeout left */
Expand All @@ -69,15 +77,11 @@ class Request extends \Swlib\Http\Request
public $_redirect_times = 0;
/** @var array 重定向的headers */
public $_redirect_headers = [];
/** @var bool */
private $_form_redirect = false;
/** @var int 已重试次数 */
private $_retried_time = 0;
public $_retried_time = 0;

const STATUS_NONE = 1;
const STATUS_WAITING = 2;

public $_status = self::STATUS_NONE;
/** @var int internal flag */
protected $_form_flag = 0;

use CookiesManagerTrait;

Expand Down Expand Up @@ -108,7 +112,7 @@ public function isWaiting(): bool
return $this->_status === self::STATUS_WAITING;
}

private function getConnectionTarget(): array
protected function getConnectionTarget(): array
{
$host = $this->uri->getHost();
if (empty($host)) {
Expand Down Expand Up @@ -427,6 +431,11 @@ public function withRetryTime(int $time): self
return $this;
}

public function getRetriedTime(): int
{
return $this->_retried_time;
}

public function withAutoIconv(bool $enable): self
{
$this->auto_iconv = $enable;
Expand Down Expand Up @@ -476,7 +485,7 @@ public function resetClient($client)
public function exec()
{
/** reset temp attributes */
if (!$this->_form_redirect) {
if (!($this->_form_flag & self::FROM_REDIRECT)) {
$this->clear();
}

Expand Down Expand Up @@ -573,7 +582,7 @@ public function exec()

/** 设定配置项 */
$settings = [
'timeout' => $this->_form_redirect && $this->_timeout ? $this->_timeout : $this->getTimeout(),
'timeout' => (($this->_form_flag & self::FROM_REDIRECT) && $this->_timeout) ? $this->_timeout : $this->getTimeout(),
'keep_alive' => $this->getKeepAlive(),
];
$settings += $this->getProxy();
Expand Down Expand Up @@ -688,7 +697,7 @@ public function recv()
}

if ($allow_redirect) {
$this->_form_redirect = true;
$this->_form_flag |= self::FROM_REDIRECT;
$this->exec();
$this->_redirect_times++;

Expand All @@ -715,7 +724,11 @@ public function recv()

/** auto retry */
while (!$response->success && $this->_retried_time++ < $this->retry_time) {
$this->callInterceptor('before_retry', $this, $response);
$ret = $this->callInterceptor('before_retry', $this, $response);
if ($ret === false) {
break;
}
$this->_form_flag |= self::FROM_RETRY;
$this->exec();
if ($this->isInQueue()) {
return $this;
Expand All @@ -740,15 +753,19 @@ public function recv()
/**
* clear tmp arguments
*/
private function clear()
protected function clear()
{
$this->_form_redirect = false;
$this->_redirect_times = 0;
$this->_redirect_headers = [];
$this->_start_time = 0;
$this->_time = 0.000;
$this->_retried_time = 0;
if (!($this->_form_flag) & self::FROM_RETRY) {
$this->_retried_time = 0;
}
$this->incremental_cookies->reset();

// should be at the end of the clear
$this->_form_flag = 0;
}

/**
Expand Down
35 changes: 35 additions & 0 deletions tests/SaberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,41 @@ public function testList()
$this->assertEquals(count($uri_list), $res->success_num);
}

public function testRetryInterceptor()
{
$count = 0;
$res = SaberGM::get(
'http://127.0.0.1:65535', [
'exception_report' => 0,
'timeout' => 0.001,
'retry_time' => 999,
'retry' => function (Saber\Request $request) use (&$count) {
$count++;
return false; // shutdown
}
]
);
$this->assertEquals(false, $res->success);
$this->assertEquals(1, $count);
}

public function testRetryTime()
{
$log = [];
$res = SaberGM::get(
'http://127.0.0.1:65535', [
'exception_report' => 0,
'timeout' => 0.001,
'retry_time' => 3,
'retry' => function (Saber\Request $request) use (&$log) {
$log[] = "retry {$request->getRetriedTime()}";
}
]
);
$this->assertEquals(false, $res->success);
$this->assertEquals(['retry 1', 'retry 2', 'retry 3'], $log);
}

public function testRetryAndAuth()
{
$uri = 'http://eu.httpbin.org/basic-auth/foo/bar';
Expand Down

0 comments on commit 5cd1134

Please sign in to comment.