Skip to content

Commit a8e1a41

Browse files
ihipoptwose
authored andcommitted
Fix keep alive when not use pool (#38)
Fix keep alive when not use the pool
1 parent 1188d0a commit a8e1a41

File tree

6 files changed

+71
-13
lines changed

6 files changed

+71
-13
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ temp/
1010
*.lock
1111
/tools
1212
/debug
13+
.phpunit.*

src/Request.php

+16-12
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public function isWaiting(): bool
115115
return $this->_status === self::STATUS_WAITING;
116116
}
117117

118-
protected function getConnectionTarget(): array
118+
public function getConnectionTarget(): array
119119
{
120120
$host = $this->uri->getHost();
121121
if (empty($host)) {
@@ -128,6 +128,12 @@ protected function getConnectionTarget(): array
128128
return ['host' => $host, 'port' => $port, 'ssl' => $ssl];
129129
}
130130

131+
public function shouldRecycleClient($client)
132+
{
133+
$connectionInfo = $this->getConnectionTarget();
134+
135+
return (!$client || ($client->host !== $connectionInfo['host'] || $client->port !== $connectionInfo['port']));
136+
}
131137
/** @return null|bool */
132138
public function getPool()
133139
{
@@ -498,24 +504,20 @@ public function exec()
498504
return $ret;
499505
}
500506

501-
/** get connection info */
502-
list($host, $port, $ssl) = array_values($this->getConnectionTarget());
503-
if ($this->client && ($this->client->host !== $host || $this->client->port !== $port)) {
507+
508+
if ($this->client && ($this->shouldRecycleClient($this->client))) {
504509
// target maybe changed
505510
$this->tryToRevertClientToPool();
506511
}
507512
if (!$this->client) {
513+
/** get connection info */
514+
$connectionInfo = $this->getConnectionTarget();
508515
/** create a new coroutine client */
509516
$client_pool = ClientPool::getInstance();
510-
if ($this->use_pool && $client = $client_pool->getEx($host, $port)) {
517+
if ($this->use_pool && $client = $client_pool->getEx($connectionInfo['host'], $connectionInfo['port'])) {
511518
$this->client = $client;
512519
} else {
513-
$options = [
514-
'host' => $host,
515-
'port' => $port,
516-
'ssl' => $ssl
517-
];
518-
$this->client = $client_pool->createEx($options, !$this->use_pool);
520+
$this->client = $client_pool->createEx($connectionInfo, !$this->use_pool);
519521
}
520522
}
521523

@@ -748,7 +750,9 @@ public function recv()
748750
}
749751
$this->client->body = '';
750752

751-
$this->tryToRevertClientToPool();
753+
if($this->use_pool){
754+
$this->tryToRevertClientToPool();
755+
}
752756

753757
return $response;
754758
}

src/Saber.php

+11
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ private function __construct(array $options = [])
147147
);
148148
}
149149

150+
/** @var \Swoole\Coroutine\Http\Client a temp client when not use pool */
151+
protected $lastTempClient;
150152
/**
151153
* @param array $options
152154
* @return Request|Response
@@ -156,6 +158,15 @@ public function request(array $options)
156158
$request = clone $this->raw;
157159
$this->setOptions($options, $request);
158160

161+
if (!$request->getPool()) {
162+
$lastTempClient =& $this->lastTempClient;
163+
if ($request->shouldRecycleClient($lastTempClient)) {
164+
$lastTempClient = $request->client = \Swlib\Saber\ClientPool::getInstance()->createEx($request->getConnectionTarget(), true);
165+
//This Temp Client will Recyle by https://github.com/swlib/saber/blob/1188d0a67d18430d5c1a11f8dcdc135852fc1e31/src/Request.php#L502-L506
166+
} else {
167+
$request->client = $lastTempClient;
168+
}
169+
}
159170
/** Psr style */
160171
if ($options['psr'] ?? false) {
161172
return $request;

tests/SaberTest.php

+27
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Swlib\Http\Exception\ServerException;
1717
use Swlib\Http\Exception\TooManyRedirectsException;
1818
use Swlib\Http\SwUploadFile;
19+
use Swlib\Http\Uri;
1920
use Swlib\Saber;
2021
use Swlib\SaberGM;
2122
use Swoole\Coroutine;
@@ -317,4 +318,30 @@ public function testFinalClear()
317318
$this->assertTrue(saber_pool_release());
318319
}
319320

321+
public function testKeepAliveAmongSameHostAndPortWithOutUsePool()
322+
{
323+
global $server_list;
324+
list($ip, $port) = array_values($server_list['httpd']);
325+
$saber = Saber::create([
326+
'base_uri' => "http://$ip:$port",
327+
//'base_uri' => "http://127.0.0.1:8081",
328+
'use_pool' => false,
329+
'exception_report' => HttpExceptionMask::E_ALL
330+
]);
331+
332+
$ReqWithSaber = $saber->get('/anything?dump_info=$ReqWithSaber')->getParsedJsonArray();
333+
$ReqWithSaber2 = $saber->get('/anything?dump_info=$ReqWithSaber2')->getParsedJsonArray();
334+
$ReqWithSaberPSR = $saber->request(['psr' => 1])->withMethod('GET')->withUri(new Uri("http://$ip:$port/anything?dump_info=ReqWithSaberPSR"))->exec()->recv()->getParsedJsonArray();
335+
$ReqWithSaberPSR2 = $saber->request(['psr' => 1])->withMethod('GET')->withUri(new Uri("http://$ip:$port/anything?dump_info=ReqWithSaberPSR2"))->exec()->recv()->getParsedJsonArray();
336+
$ReqAfterAnotherPort = $saber->get('http://httpbin.org/anything?dump_info=$ReqWithSaber2')->getParsedJsonArray();
337+
$ReqAfterAnotherPort = $saber->get('/anything?dump_info=$ReqWithSaber2')->getParsedJsonArray();
338+
339+
$this->assertTrue($ReqWithSaber['server']['remote_port'] === $ReqWithSaber2['server']['remote_port']);
340+
$this->assertTrue($ReqWithSaberPSR['server']['remote_port'] === $ReqWithSaberPSR2['server']['remote_port']);
341+
$this->assertTrue($ReqWithSaber2['server']['remote_port'] === $ReqWithSaberPSR2['server']['remote_port']);
342+
$this->assertFalse($ReqWithSaber2['server']['remote_port'] === $ReqAfterAnotherPort['server']['remote_port']);
343+
$this->assertTrue($ReqWithSaber2['header']['connection'] === 'keep-alive');
344+
$this->assertTrue($ReqWithSaberPSR2['header']['connection'] === 'keep-alive');
345+
}
346+
320347
}

tests/servers/httpd.php

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
/**
3+
* Copyright: Swlib
4+
* Author: Twosee <[email protected]>
5+
* Maintainer: ihipop <[email protected]>
6+
* Date: 2019年04月23日17:57:10
7+
*/
8+
9+
$http = new Swoole\Http\Server($argv[1], $argv[2]);
10+
$http->set(['worker_num' => 1, 'log_file' => '/dev/null']);
11+
$http->on('request', function ($request, $response) {
12+
$response->end(json_encode($request,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES));
13+
});
14+
$http->start();

tests/servers/manager.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ function run_server(string $file): array
4343
}
4444

4545
return [
46-
'mixed' => run_server(__DIR__ . '/mixed.php')
46+
'mixed' => run_server(__DIR__ . '/mixed.php'),
47+
'httpd' => run_server(__DIR__ . '/httpd.php')
4748
];
4849
})();

0 commit comments

Comments
 (0)