fix: 自动清理过期的chunk

This commit is contained in:
Lan
2025-12-01 15:24:47 +08:00
parent c1966b3942
commit e854eb068c
3 changed files with 12 additions and 14 deletions
-1
View File
@@ -51,7 +51,6 @@ class UploadChunk(models.Model):
file_name = fields.CharField(max_length=255)
created_at = fields.DatetimeField(auto_now_add=True)
completed = fields.BooleanField(default=False)
actual_size = fields.IntField(null=True) # 实际接收的分片大小
class KeyValue(Model):
+12 -12
View File
@@ -266,13 +266,14 @@ async def upload_chunk(
detail=f"分片大小超过声明值: 最大 {chunk_info.chunk_size}, 实际 {chunk_size}"
)
# 计算已上传的实际总大小(防止绕过前端限制
uploaded_chunks_list = await UploadChunk.filter(
# 计算已上传分片数,校验累计大小不超限(用分片数 * chunk_size 估算
uploaded_count = await UploadChunk.filter(
upload_id=upload_id,
completed=True
).all()
uploaded_size = sum(c.actual_size for c in uploaded_chunks_list if c.actual_size)
if uploaded_size + chunk_size > settings.uploadSize:
).count()
# 已上传分片的最大可能大小 + 当前分片
max_uploaded_size = uploaded_count * chunk_info.chunk_size + chunk_size
if max_uploaded_size > settings.uploadSize:
max_size_mb = settings.uploadSize / (1024 * 1024)
raise HTTPException(
status_code=403,
@@ -291,7 +292,7 @@ async def upload_chunk(
except Exception as e:
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"分片保存失败: {str(e)}")
# 更新或创建分片记录(保存成功后再记录,包含实际大小
# 更新或创建分片记录(保存成功后再记录)
await UploadChunk.update_or_create(
upload_id=upload_id,
chunk_index=chunk_index,
@@ -301,8 +302,7 @@ async def upload_chunk(
'file_size': chunk_info.file_size,
'total_chunks': chunk_info.total_chunks,
'chunk_size': chunk_info.chunk_size,
'file_name': chunk_info.file_name,
'actual_size': chunk_size
'file_name': chunk_info.file_name
}
)
return APIResponse(detail={"chunk_hash": chunk_hash})
@@ -372,9 +372,9 @@ async def complete_upload(upload_id: str, data: CompleteUploadModel, ip: str = D
if len(completed_chunks_list) != chunk_info.total_chunks:
raise HTTPException(status.HTTP_400_BAD_REQUEST, detail="分片不完整")
# 计算实际上传的总大小并校验
actual_total_size = sum(c.actual_size for c in completed_chunks_list if c.actual_size)
if actual_total_size > settings.uploadSize:
# 用分片数 * chunk_size 校验最大可能大小
max_total_size = len(completed_chunks_list) * chunk_info.chunk_size
if max_total_size > settings.uploadSize:
# 清理已上传的分片
_, _, _, _, save_path = await get_chunk_file_path_name(chunk_info.file_name, upload_id)
try:
@@ -401,7 +401,7 @@ async def complete_upload(upload_id: str, data: CompleteUploadModel, ip: str = D
file_hash=file_hash, # 使用合并后计算的哈希
is_chunked=True,
upload_id=upload_id,
size=actual_total_size, # 使用实际上传大小而非前端声明值
size=chunk_info.file_size,
expired_at=expired_at,
expired_count=expired_count,
used_count=used_count,
-1
View File
@@ -50,7 +50,6 @@ async def clean_incomplete_uploads():
file_storage: FileStorageInterface = storages[settings.file_storage]()
# 默认 24 小时未完成的上传视为过期
expire_hours = getattr(settings, 'chunk_expire_hours', 24)
while True:
try:
expire_time = datetime.datetime.now() - datetime.timedelta(hours=expire_hours)