Skip to content

Commit 03fea73

Browse files
authored
feat: pre conn pool (TencentCloud#175)
* feat: pre conn pool * doc: hunyuan example
1 parent e060c08 commit 03fea73

File tree

5 files changed

+99
-14
lines changed

5 files changed

+99
-14
lines changed

examples/hunyuan/v20230901/chat_std.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from tencentcloud.common import credential
66
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
7+
from tencentcloud.common.profile.client_profile import ClientProfile
78
from tencentcloud.hunyuan.v20230901 import hunyuan_client, models
89

910
try:
@@ -12,7 +13,10 @@
1213
os.environ.get("TENCENTCLOUD_SECRET_ID"),
1314
os.environ.get("TENCENTCLOUD_SECRET_KEY"))
1415

15-
client = hunyuan_client.HunyuanClient(cred, "ap-guangzhou")
16+
cpf = ClientProfile()
17+
# 预先建立连接可以降低访问延迟
18+
cpf.httpProfile.pre_conn_pool_size = 3
19+
client = hunyuan_client.HunyuanClient(cred, "ap-guangzhou", cpf)
1620

1721
req = models.ChatStdRequest()
1822
msg = models.Message()

tencentcloud/common/abstract_client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ def __init__(self, credential, region, profile=None):
7777
req_timeout=self.profile.httpProfile.reqTimeout,
7878
proxy=self.profile.httpProfile.proxy,
7979
is_http=is_http,
80-
certification=self.profile.httpProfile.certification)
80+
certification=self.profile.httpProfile.certification,
81+
pre_conn_pool_size=self.profile.httpProfile.pre_conn_pool_size)
8182
if self.profile.httpProfile.keepAlive:
8283
self.request.set_keep_alive()
8384
self.circuit_breaker = None
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
import logging
4+
import threading
5+
6+
from requests.adapters import HTTPAdapter
7+
from urllib3 import HTTPSConnectionPool, PoolManager, HTTPConnectionPool
8+
9+
logger = logging.getLogger("tencentcloud_sdk_common")
10+
11+
12+
class HTTPSPreConnPool(HTTPSConnectionPool):
13+
_close_signal = {}
14+
15+
def __init__(self, *args, **kwargs):
16+
super(HTTPSPreConnPool, self).__init__(*args, **kwargs)
17+
# clear the pool
18+
for _ in range(self.pool.maxsize):
19+
self.pool.get()
20+
self._conn_producer = threading.Thread(target=self._conn_producer_loop)
21+
self._conn_producer.setDaemon(True)
22+
self._conn_producer.start()
23+
24+
def _conn_producer_loop(self):
25+
while True:
26+
conn = super(HTTPSPreConnPool, self)._new_conn()
27+
conn.connect()
28+
logger.debug("HTTPSPreConnPool: created a new conn")
29+
self.pool.put(conn)
30+
31+
32+
class HTTPPreConnPool(HTTPConnectionPool):
33+
_close_signal = {}
34+
35+
def __init__(self, *args, **kwargs):
36+
super(HTTPPreConnPool, self).__init__(*args, **kwargs)
37+
# clear the pool
38+
for _ in range(self.pool.maxsize):
39+
self.pool.get()
40+
self._conn_producer = threading.Thread(target=self._conn_producer_loop)
41+
self._conn_producer.setDaemon(True)
42+
self._conn_producer.start()
43+
44+
def _conn_producer_loop(self):
45+
while True:
46+
conn = super(HTTPPreConnPool, self)._new_conn()
47+
conn.connect()
48+
logger.debug("HTTPSPreConnPool: created a new conn")
49+
self.pool.put(conn)
50+
51+
52+
class PreConnPoolManager(PoolManager):
53+
def __init__(self, pool_size, *args, **kwargs):
54+
self._pool_size = pool_size
55+
super(PreConnPoolManager, self).__init__(*args, **kwargs)
56+
57+
def _new_pool(self, scheme, host, port, request_context):
58+
if scheme == 'https':
59+
return HTTPSPreConnPool(host, port, maxsize=self._pool_size - 1)
60+
if scheme == 'http':
61+
return HTTPPreConnPool(host, port, maxsize=self._pool_size - 1)
62+
return super(PreConnPoolManager, self)._new_pool(scheme, host, port, request_context)
63+
64+
65+
class PreConnAdapter(HTTPAdapter):
66+
def __init__(self, conn_pool_size, *args, **kwargs):
67+
self._conn_pool_size = conn_pool_size
68+
super(PreConnAdapter, self).__init__(*args, **kwargs)
69+
70+
def init_poolmanager(self, *args, **kwargs):
71+
self.poolmanager = PreConnPoolManager(self._conn_pool_size, *args, **kwargs)

tencentcloud/common/http/request.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
# -*- coding: utf-8 -*-
33

44
import os
5-
import socket
65
import logging
6+
77
import requests
88
import certifi
99

10+
from tencentcloud.common.http.pre_conn import PreConnAdapter
11+
1012
try:
1113
from urllib.parse import urlparse
1214
except ImportError:
@@ -25,7 +27,7 @@ def _get_proxy_from_env(host, varname="HTTPS_PROXY"):
2527

2628

2729
class ProxyConnection(object):
28-
def __init__(self, host, timeout=60, proxy=None, certification=None, is_http=False):
30+
def __init__(self, host, timeout=60, proxy=None, certification=None, is_http=False, pre_conn_pool_size=0):
2931
self.request_host = host
3032
self.certification = certification
3133
if certification is None:
@@ -39,23 +41,29 @@ def __init__(self, host, timeout=60, proxy=None, certification=None, is_http=Fal
3941
if proxy:
4042
self.proxy = {"http": proxy, "https": proxy}
4143
self.request_length = 0
44+
self._session = requests.Session()
45+
if pre_conn_pool_size > 0:
46+
adapter = PreConnAdapter(conn_pool_size=pre_conn_pool_size)
47+
self._session.mount("https://", adapter)
48+
self._session.mount("http://", adapter)
4249

4350
def request(self, method, url, body=None, headers=None):
4451
headers.setdefault("Host", self.request_host)
45-
return requests.request(method=method,
46-
url=url,
47-
data=body,
48-
headers=headers,
49-
proxies=self.proxy,
50-
verify=self.certification,
51-
timeout=self.timeout,
52-
stream=True)
52+
return self._session.request(method=method,
53+
url=url,
54+
data=body,
55+
headers=headers,
56+
proxies=self.proxy,
57+
verify=self.certification,
58+
timeout=self.timeout,
59+
stream=True)
5360

5461

5562
class ApiRequest(object):
56-
def __init__(self, host, req_timeout=60, debug=False, proxy=None, is_http=False, certification=None):
63+
def __init__(self, host, req_timeout=60, debug=False, proxy=None, is_http=False, certification=None,
64+
pre_conn_pool_size=0):
5765
self.conn = ProxyConnection(host, timeout=req_timeout, proxy=proxy, certification=certification,
58-
is_http=is_http)
66+
is_http=is_http, pre_conn_pool_size=pre_conn_pool_size)
5967
self.is_http = is_http
6068
self.host = host
6169
self.req_timeout = req_timeout

tencentcloud/common/profile/http_profile.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,4 @@ def __init__(self, protocol=None, endpoint=None, reqMethod="POST", reqTimeout=60
4141
self.rootDomain = "tencentcloudapi.com" if rootDomain is None else rootDomain
4242
self.certification = certification
4343
self.apigw_endpoint = None
44+
self.pre_conn_pool_size = 0

0 commit comments

Comments
 (0)