109Implement a streaming upload manager supporting chunking, bounded concurrency, progress, retry, and cancellation
Problem
Uploading a 2 GB video in one request fails on any network hiccup and shows no progress. Implement uploadFile(file, options), which uploads a Blob or File in chunks:
await uploadFile(file, {
chunkSize: 5 * 1024 * 1024,
concurrency: 3,
retries: 2,
uploadChunk: ({ index, start, end, blob, signal }) =>
fetch(`/upload/${uploadId}/${index}`, { method: "PUT", body: blob, signal }).then((r) => {
if (!r.ok) throw new Error(`HTTP ${r.status}`);
}),
onProgress: ({ loaded, total, percent }) => (bar.value = percent),
signal: controller.signal,
});Options: chunkSize, concurrency = 3, retries = 2, uploadChunk, onProgress = () => {}, signal, retryDelay = (attempt) => 100 * 2 ** attempt and sleep = (ms) => new Promise(…) (injectable for tests).
Requirements
- Chunk
icovers bytes[i * chunkSize, min(size, (i + 1) * chunkSize));blobis that slice. - At most
concurrencychunks upload at once. - Retry a failed chunk up to
retriestimes, waitingretryDelay(attempt)between tries (attempt 0 for the first retry). Never retry after cancellation. onProgress({ loaded, total, percent })after each chunk finishes;loadedonly counts finished chunks, so it never goes backwards;percentis rounded and reaches 100.- If a chunk still fails after its retries, abort the other in-flight chunks, start no new ones, and reject with an
Errorwhose message isChunk {i} failed after {n} attemptsand whosecauseis the last error. - If
signalaborts, abort in-flight chunks, start no new ones and reject withsignal.reason. - Resolve with
{ chunks, size }. An empty file resolves immediately with{ chunks: 0, size: 0 }.
Try it yourself
Write your solution, run it, then submit to check it against the tests.
Press Run or ⌘ Enter to execute your code.
Step-by-step
count = Math.ceil(size / chunkSize). Chunk boundaries are pure arithmetic, and file.slice(start, end) creates a lightweight view without reading the bytes into memory.
Unlock the full solution
What's inside
- Step-by-step
- Approach
- Solution
- Complexity
- Edge cases
- Follow-up questions
- Tests
Includes 2 code listings, 6 edge cases, 4 follow-up questions.
One-time payment by UPI, card or net banking. Launch price.