Skip to content

Commit 6b728ab

Browse files
committed
perf: 复用ClientSession提升文件下载性能
1 parent ff1943d commit 6b728ab

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

core/storage.py

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,11 @@ async def get_file_response(self, file_code: FileCodes):
337337
ExpiresIn=3600,
338338
)
339339

340+
# 创建ClientSession并传递给生成器复用
341+
session = aiohttp.ClientSession()
342+
340343
async def stream_generator():
341-
async with aiohttp.ClientSession() as session:
344+
try:
342345
async with session.get(link) as resp:
343346
if resp.status != 200:
344347
raise HTTPException(
@@ -352,6 +355,8 @@ async def stream_generator():
352355
if not chunk:
353356
break
354357
yield chunk
358+
finally:
359+
await session.close()
355360

356361
from fastapi.responses import StreamingResponse
357362
encoded_filename = quote(filename, safe='')
@@ -647,18 +652,20 @@ async def get_file_response(self, file_code: FileCodes):
647652

648653
content_length = file_code.size # 默认使用数据库中的大小
649654

655+
# 创建ClientSession并复用
656+
session = aiohttp.ClientSession()
657+
650658
# 尝试发送HEAD请求获取Content-Length
651659
try:
652-
async with aiohttp.ClientSession() as session:
653-
async with session.head(link) as resp:
654-
if resp.status == 200 and 'Content-Length' in resp.headers:
655-
content_length = int(resp.headers['Content-Length'])
660+
async with session.head(link) as resp:
661+
if resp.status == 200 and 'Content-Length' in resp.headers:
662+
content_length = int(resp.headers['Content-Length'])
656663
except Exception:
657664
# 如果HEAD请求失败,继续使用默认大小
658665
pass
659666

660667
async def stream_generator():
661-
async with aiohttp.ClientSession() as session:
668+
try:
662669
async with session.get(link) as resp:
663670
if resp.status != 200:
664671
raise HTTPException(
@@ -671,6 +678,8 @@ async def stream_generator():
671678
if not chunk:
672679
break
673680
yield chunk
681+
finally:
682+
await session.close()
674683

675684
encoded_filename = quote(filename, safe='')
676685
headers = {
@@ -1080,22 +1089,22 @@ async def get_file_response(self, file_code: FileCodes):
10801089
url = self._build_url(await file_code.get_file_path())
10811090
content_length = file_code.size # 默认使用数据库中的大小
10821091

1092+
# 创建ClientSession并复用(包含认证头)
1093+
session = aiohttp.ClientSession(headers={
1094+
"Authorization": f"Basic {base64.b64encode(f'{settings.webdav_username}:{settings.webdav_password}'.encode()).decode()}"
1095+
})
1096+
10831097
# 尝试发送HEAD请求获取Content-Length
10841098
try:
1085-
async with aiohttp.ClientSession(headers={
1086-
"Authorization": f"Basic {base64.b64encode(f'{settings.webdav_username}:{settings.webdav_password}'.encode()).decode()}"
1087-
}) as session:
1088-
async with session.head(url) as resp:
1089-
if resp.status == 200 and 'Content-Length' in resp.headers:
1090-
content_length = int(resp.headers['Content-Length'])
1099+
async with session.head(url) as resp:
1100+
if resp.status == 200 and 'Content-Length' in resp.headers:
1101+
content_length = int(resp.headers['Content-Length'])
10911102
except Exception:
10921103
# 如果HEAD请求失败,继续使用默认大小
10931104
pass
10941105

10951106
async def stream_generator():
1096-
async with aiohttp.ClientSession(headers={
1097-
"Authorization": f"Basic {base64.b64encode(f'{settings.webdav_username}:{settings.webdav_password}'.encode()).decode()}"
1098-
}) as session:
1107+
try:
10991108
async with session.get(url) as resp:
11001109
if resp.status != 200:
11011110
raise HTTPException(
@@ -1108,6 +1117,8 @@ async def stream_generator():
11081117
if not chunk:
11091118
break
11101119
yield chunk
1120+
finally:
1121+
await session.close()
11111122

11121123
encoded_filename = quote(filename, safe='')
11131124
headers = {

0 commit comments

Comments
 (0)