diff --git a/packages/forms/src/components/form/UploadBigFile/uploadBigFileClient.ts b/packages/forms/src/components/form/UploadBigFile/uploadBigFileClient.ts index 5410edc..4ccc801 100644 --- a/packages/forms/src/components/form/UploadBigFile/uploadBigFileClient.ts +++ b/packages/forms/src/components/form/UploadBigFile/uploadBigFileClient.ts @@ -4,6 +4,7 @@ type ProgressCallback = (progress: number, total: number) => void; export type BigFileUploadOptions = { retryChunks: number; + retryDelay?: number; chunkSize: number; parallelChunks: number; parallelUploads: number; @@ -11,6 +12,7 @@ export type BigFileUploadOptions = { const UPLOAD_BIG_FILE_OPTIONS: BigFileUploadOptions = { retryChunks: 5, + retryDelay: 1000, chunkSize: 1024 * 1024 * 5, parallelChunks: 3, parallelUploads: 3, @@ -81,38 +83,32 @@ async function uploadBigFile(fileId: string, file: File, progressCallback: Progr total: totalChunks, }; - const uploadPromiseWithRetry = (async function uploadPromise(retry = options.retryChunks) { - const upload = uploadChunkWithXHR(chunk, info, (loaded) => { + const uploadPromiseWithRetry = retry(async () => { + const upload = await uploadChunkWithXHR(chunk, info, (loaded) => { activeLoads.set(i, loaded); const loadedSize = Array.from(activeLoads.values()).reduce((a, b) => a + b, 0); progressCallback(finishedSize + loadedSize, totalSize); }); - try { - const response: any = await upload; - if (response?.missingChunks && activeChunks.size < options.parallelChunks) { - const promises: Promise[] = []; - for (const chunk of response.missingChunks) { - const {promise} = await uploadChunk(chunk - 1); - promises.push(promise); - } - await Promise.all(promises); + const response: any = await upload; + if (response?.missingChunks && activeChunks.size < options.parallelChunks) { + const promises: Promise[] = []; + for (const chunk of response.missingChunks) { + const { promise } = await uploadChunk(chunk - 1); + promises.push(promise); } + await Promise.all(promises); + } - if (!response?.ok) { - throw new Error(response.error); - } - } catch (error) { - if (retry === 0) { - throw error; - } - return await uploadPromise(retry - 1); + if (!response?.ok) { + throw new Error(response.error); } - })().then(() => { - activeLoads.delete(i); - activeChunks.delete(uploadPromiseWithRetry); - finishedSize += chunk.size; - }); + }, { retries: options.retryChunks, delay: options.retryDelay }) + .then(() => { + activeLoads.delete(i); + activeChunks.delete(uploadPromiseWithRetry); + finishedSize += chunk.size; + }); activeChunks.add(uploadPromiseWithRetry); return { promise: uploadPromiseWithRetry }; @@ -222,4 +218,20 @@ export function finishFormSubmission(form: HTMLFormElement, onClick?: string) { } form.submit(); +} + +async function retry(fn: () => Promise, options: { retries: number, delay: number; } = { retries: 5, delay: 1000 }) { + let attempts = 0; + while (attempts < options.retries) { + try { + await fn(); + return; + } catch (error) { + attempts++; + if (attempts >= options.retries) { + throw error; + } + await new Promise(res => setTimeout(res, options.delay)); + } + } } \ No newline at end of file diff --git a/packages/forms/src/components/form/UploadBigFile/uploadBigFileServer.ts b/packages/forms/src/components/form/UploadBigFile/uploadBigFileServer.ts index f0b40c1..aa61f2c 100644 --- a/packages/forms/src/components/form/UploadBigFile/uploadBigFileServer.ts +++ b/packages/forms/src/components/form/UploadBigFile/uploadBigFileServer.ts @@ -89,12 +89,12 @@ export async function loadUploadFiles(astro: AstroGlobal, options: Partial maxDirectorySize) { return await sendError("Directory size exceeded"); } - const newTotalSize = (await totalDirectorySize(uploadDir)) + uploadSize; + const newTotalSize = (await totalDirectorySize(uploadDir)) + uploadFileMayBe.size; if (newTotalSize > maxUploadSize) { return await sendError("Upload size exceeded"); }