Skip to content

Commit 3dd3b1f

Browse files
committed
perf(sdk-recorder): upload chunks concurrently in batches of 3
1 parent 72fa86d commit 3dd3b1f

1 file changed

Lines changed: 41 additions & 30 deletions

File tree

packages/sdk-recorder/src/upload/multipart-client.ts

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -61,41 +61,52 @@ export class MultipartClient {
6161
size: number;
6262
}> = [];
6363

64-
for (let i = 0; i < totalParts; i++) {
65-
const start = i * CHUNK_SIZE;
66-
const end = Math.min(start + CHUNK_SIZE, blob.size);
67-
const chunk = blob.slice(start, end);
68-
const partNumber = i + 1;
69-
70-
const { presignedUrl } = await this.request(
71-
"/upload/multipart/presign-part",
72-
{
73-
videoId,
74-
uploadId,
75-
partNumber,
76-
},
64+
const CONCURRENCY = 3;
65+
for (let i = 0; i < totalParts; i += CONCURRENCY) {
66+
const batch = Array.from(
67+
{ length: Math.min(CONCURRENCY, totalParts - i) },
68+
(_, j) => i + j,
7769
);
7870

79-
const uploadResponse = await fetch(presignedUrl, {
80-
method: "PUT",
81-
body: chunk,
82-
});
71+
const results = await Promise.all(
72+
batch.map(async (idx) => {
73+
const start = idx * CHUNK_SIZE;
74+
const end = Math.min(start + CHUNK_SIZE, blob.size);
75+
const chunk = blob.slice(start, end);
76+
const partNumber = idx + 1;
77+
78+
const { presignedUrl } = await this.request(
79+
"/upload/multipart/presign-part",
80+
{
81+
videoId,
82+
uploadId,
83+
partNumber,
84+
},
85+
);
8386

84-
if (!uploadResponse.ok) {
85-
await this.request("/upload/multipart/abort", {
86-
videoId,
87-
uploadId,
88-
});
89-
throw new Error(`Failed to upload part ${partNumber}`);
90-
}
87+
const uploadResponse = await fetch(presignedUrl, {
88+
method: "PUT",
89+
body: chunk,
90+
});
9191

92-
const etag = uploadResponse.headers.get("ETag") ?? "";
93-
completedParts.push({
94-
partNumber,
95-
etag,
96-
size: end - start,
97-
});
92+
if (!uploadResponse.ok) {
93+
await this.request("/upload/multipart/abort", {
94+
videoId,
95+
uploadId,
96+
});
97+
throw new Error(`Failed to upload part ${partNumber}`);
98+
}
99+
100+
const etag = uploadResponse.headers.get("ETag") ?? "";
101+
return {
102+
partNumber,
103+
etag,
104+
size: end - start,
105+
};
106+
}),
107+
);
98108

109+
completedParts.push(...results);
99110
options?.onProgress?.(completedParts.length / totalParts);
100111
}
101112

0 commit comments

Comments
 (0)