41 lines
1.2 KiB
TypeScript
41 lines
1.2 KiB
TypeScript
import { deleteFromS3 } from '@/lib/s3'
|
|
|
|
export const S3_COMPENSATION_DELETE_CONCURRENCY = 3
|
|
|
|
/**
|
|
* 失败补偿需要尽量删除所有已上传对象,但不能一次向 MinIO 发出无限量请求。
|
|
* 返回值保持 Promise.allSettled 的语义:单个删除失败不会阻断其余对象清理。
|
|
*/
|
|
export async function deleteS3ObjectsWithLimit(
|
|
fileUrls: string[],
|
|
concurrency = S3_COMPENSATION_DELETE_CONCURRENCY,
|
|
): Promise<PromiseSettledResult<void>[]> {
|
|
if (fileUrls.length === 0) {
|
|
return []
|
|
}
|
|
|
|
const normalizedConcurrency = Number.isFinite(concurrency)
|
|
? Math.max(1, Math.floor(concurrency))
|
|
: S3_COMPENSATION_DELETE_CONCURRENCY
|
|
const workerCount = Math.min(normalizedConcurrency, fileUrls.length)
|
|
const results = new Array<PromiseSettledResult<void>>(fileUrls.length)
|
|
let nextIndex = 0
|
|
|
|
const worker = async () => {
|
|
while (nextIndex < fileUrls.length) {
|
|
const index = nextIndex
|
|
nextIndex += 1
|
|
|
|
try {
|
|
await deleteFromS3(fileUrls[index])
|
|
results[index] = { status: 'fulfilled', value: undefined }
|
|
} catch (reason) {
|
|
results[index] = { status: 'rejected', reason }
|
|
}
|
|
}
|
|
}
|
|
|
|
await Promise.all(Array.from({ length: workerCount }, () => worker()))
|
|
return results
|
|
}
|