Skip to content

Commit 5c240e7

Browse files
amuluowintwose
andauthored
Support custom pool key (#127)
Co-authored-by: twosee <[email protected]>
1 parent 2d6b502 commit 5c240e7

File tree

5 files changed

+44
-23
lines changed

5 files changed

+44
-23
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ go(function(){
486486
| retry | callable | 自动重试拦截器 | `function(Request $request, Response $response){}` | 位于发生错误后及重试之前 |
487487
| retry_time | int | 自动重试次数 | | 默认不重试 |
488488
| use_pool | bool\|int | 连接池 | `true` | `false` |
489+
| pool_key | callable\|array | 连接池的key | `function(Request $request):string { return $key; }` | 默认为请求地址的`host:port` |
489490

490491
### 配置参数别名
491492

src/ClientPool.php

+10-14
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@ public function createEx(array $options, bool $temp = false)
2525
);
2626
}
2727
$client = new Client($options['host'], $options['port'], $options['ssl']);
28-
if ($temp) {
29-
return $client; // not record
30-
} else {
31-
$key = "{$options['host']}:{$options['port']}";
28+
if (!$temp) {
29+
$key = $options['pool_key'] ?? "{$options['host']}:{$options['port']}";
3230
parent::create($options, $key);
33-
return $client;
31+
/** @noinspection PhpUndefinedFieldInspection */
32+
$client->pool_key = $key;
3433
}
34+
return $client;
3535
}
3636

3737
public function setMaxEx(array $options, int $max_size = -1): int
3838
{
39-
$key = "{$options['host']}:{$options['port']}";
39+
$key = $options['pool_key'] ?? "{$options['host']}:{$options['port']}";
4040
$ret = parent::setMax($key, $max_size);
4141
if ($ret === -1) { // chan reduce max size
4242
$chan = $this->resource_map[$key];
@@ -54,10 +54,10 @@ public function setMaxEx(array $options, int $max_size = -1): int
5454
return $ret;
5555
}
5656

57-
public function getEx(string $host, string $port): ?Client
57+
public function getEx(array $options): ?Client
5858
{
5959
/** @var $client Client */
60-
$key = "{$host}:{$port}";
60+
$key = $options['pool_key'] ?? "{$options['host']}:{$options['port']}";
6161
$client = parent::get($key);
6262
if ($client && SABER_SW_LE_V401 && !$client->isConnected()) {
6363
@$this->status_map[$key]['disconnected']++;
@@ -68,17 +68,13 @@ public function getEx(string $host, string $port): ?Client
6868

6969
public function putEx(Client $client)
7070
{
71-
/** @var $client Client */
72-
if (!($client instanceof Client)) {
73-
throw new InvalidArgumentException('$value should be instance of ' . Client::class);
74-
}
75-
parent::put($client, "{$client->host}:{$client->port}");
71+
parent::put($client, $client->pool_key ?? "{$client->host}:{$client->port}");
7672
}
7773

7874
public function destroyEx(Client $client)
7975
{
8076
$client->close();
81-
parent::destroy($client, "{$client->host}:{$client->port}");
77+
parent::destroy($client, $client->pool_key ?? "{$client->host}:{$client->port}");
8278
}
8379

8480
public function release(string $key)

src/Request.php

+11-5
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,11 @@ public function withPool($bool_or_max_size): self
215215
$this->use_pool = $bool_or_max_size;
216216
if (is_numeric($this->use_pool)) {
217217
// limit max num
218-
ClientPool::getInstance()->setMaxEx($this->getConnectionTarget(), $bool_or_max_size);
218+
$connectionTarget = $this->getConnectionTarget();
219+
if (($key = $this->callInterceptor('pool_key', $this))) {
220+
$connectionTarget['pool_key'] = $key;
221+
}
222+
ClientPool::getInstance()->setMaxEx($connectionTarget, $bool_or_max_size);
219223
}
220224
if ($bool_or_max_size) {
221225
$this->withKeepAlive(true);
@@ -650,11 +654,13 @@ public function exec()
650654
$connectionInfo = $this->getConnectionTarget();
651655
/** create a new coroutine client */
652656
$client_pool = ClientPool::getInstance();
653-
if ($this->use_pool && $client = $client_pool->getEx($connectionInfo['host'], $connectionInfo['port'])) {
654-
$this->client = $client;
655-
} else {
656-
$this->client = $client_pool->createEx($connectionInfo, !$this->use_pool);
657+
if ($this->use_pool) {
658+
if (($key = $this->callInterceptor('pool_key', $this))) {
659+
$connectionInfo['pool_key'] = $key;
660+
}
661+
$client = $client_pool->getEx($connectionInfo);
657662
}
663+
$this->client = $client ?? $client_pool->createEx($connectionInfo, !$this->use_pool);
658664
}
659665

660666
/** Clear useless cookies property */

src/Saber.php

+8-4
Original file line numberDiff line numberDiff line change
@@ -469,10 +469,6 @@ private static function transOptionsToRequest(array $options, Request $request)
469469
);
470470
}
471471

472-
if (isset($options['use_pool'])) {
473-
$request->withPool($options['use_pool']);
474-
}
475-
476472
if (!empty($options['uri_query']) && $uri = $request->getUri()) {
477473
$uri->withQuery(DataParser::toQueryString(($options['uri_query'])));
478474
}
@@ -661,6 +657,10 @@ private static function transOptionsToRequest(array $options, Request $request)
661657
$request->withAddedInterceptor('before_retry', (array)$options['before_retry']);
662658
}
663659

660+
if(!empty($options['pool_key'])){
661+
$request->withAddedInterceptor('pool_key', (array)$options['pool_key']);
662+
}
663+
664664
/** register Interceptor before request */
665665
if (!empty($options['before'])) {
666666
$request->withAddedInterceptor('request', (array)$options['before']);
@@ -679,6 +679,10 @@ private static function transOptionsToRequest(array $options, Request $request)
679679
if (!empty($options['exception_handle'])) {
680680
$request->withAddedInterceptor('exception', (array)$options['exception_handle']);
681681
}
682+
683+
if (isset($options['use_pool'])) {
684+
$request->withPool($options['use_pool']);
685+
}
682686
}
683687

684688
private static function mergeOptions(array $options, ... $defaults)

tests/SaberTest.php

+14
Original file line numberDiff line numberDiff line change
@@ -427,4 +427,18 @@ public function testNonRedirect()
427427
$res = $saber->get('http://baidu.com', ['redirect' => 0]);
428428
$this->assertTrue((string)$res->body !== '');
429429
}
430+
431+
public function testPoolKeyConfig(){
432+
$saber = Saber::create(['exception_report' => true]);
433+
$saber->get('http://www.httpbin.org', ['use_pool' => 5, 'pool_key' => function (Saber\Request $request) {
434+
return 'test_pool';
435+
}]);
436+
$this->assertEquals(saber_pool_get_status('test_pool')['max'], 5);
437+
}
438+
439+
public function testNoPoolKeyConfig(){
440+
$saber = Saber::create(['exception_report' => true]);
441+
$saber->get('http://www.httpbin.org', ['use_pool' => 5]);
442+
$this->assertEquals(saber_pool_get_status('www.httpbin.org:80')['max'], 5);
443+
}
430444
}

0 commit comments

Comments
 (0)