feat: implement dynamic upload timeout based on file size across components (#246)

This commit is contained in:
Daniel Luiz Alves
2025-09-09 10:40:01 -03:00
committed by GitHub
3 changed files with 48 additions and 2 deletions

View File

@@ -150,6 +150,18 @@ export function FileUploadSection({ reverseShare, password, alias, onUploadSucce
return fileName.split(".").pop() || "";
};
const calculateUploadTimeout = (fileSize: number): number => {
const baseTimeout = 300000;
const fileSizeMB = fileSize / (1024 * 1024);
if (fileSizeMB > 500) {
const extraMB = fileSizeMB - 500;
const extraMinutes = Math.ceil(extraMB / 100);
return baseTimeout + extraMinutes * 60000;
}
return baseTimeout;
};
const uploadFileToStorage = async (
file: File,
presignedUrl: string,
@@ -172,10 +184,14 @@ export function FileUploadSection({ reverseShare, password, alias, onUploadSucce
throw new Error(result.error || "Chunked upload failed");
}
} else {
const uploadTimeout = calculateUploadTimeout(file.size);
await axios.put(presignedUrl, file, {
headers: {
"Content-Type": file.type,
},
timeout: uploadTimeout,
maxContentLength: Infinity,
maxBodyLength: Infinity,
onUploadProgress: (progressEvent) => {
if (onProgress && progressEvent.total) {
const progress = (progressEvent.loaded / progressEvent.total) * 100;

View File

@@ -64,6 +64,18 @@ export function GlobalDropZone({ onSuccess, children, currentFolderId }: GlobalD
[generateFileId]
);
const calculateUploadTimeout = useCallback((fileSize: number): number => {
const baseTimeout = 300000;
const fileSizeMB = fileSize / (1024 * 1024);
if (fileSizeMB > 500) {
const extraMB = fileSizeMB - 500;
const extraMinutes = Math.ceil(extraMB / 100);
return baseTimeout + extraMinutes * 60000;
}
return baseTimeout;
}, []);
const handleDragOver = useCallback((event: DragEvent) => {
event.preventDefault();
event.stopPropagation();
@@ -158,11 +170,16 @@ export function GlobalDropZone({ onSuccess, children, currentFolderId }: GlobalD
folderId: currentFolderId,
});
} else {
const uploadTimeout = calculateUploadTimeout(file.size);
await axios.put(url, file, {
headers: {
"Content-Type": file.type,
},
signal: abortController.signal,
timeout: uploadTimeout, // Dynamic timeout based on file size
maxContentLength: Infinity,
maxBodyLength: Infinity,
onUploadProgress: (progressEvent: any) => {
const progress = (progressEvent.loaded / (progressEvent.total || file.size)) * 100;
setFileUploads((prev) => prev.map((u) => (u.id === id ? { ...u, progress: Math.round(progress) } : u)));
@@ -203,7 +220,7 @@ export function GlobalDropZone({ onSuccess, children, currentFolderId }: GlobalD
);
}
},
[t, isS3Enabled, currentFolderId]
[t, isS3Enabled, currentFolderId, calculateUploadTimeout]
);
const handleDrop = useCallback(

View File

@@ -231,6 +231,18 @@ export function UploadFileModal({ isOpen, onClose, onSuccess, currentFolderId }:
);
};
const calculateUploadTimeout = (fileSize: number): number => {
const baseTimeout = 300000;
const fileSizeMB = fileSize / (1024 * 1024);
if (fileSizeMB > 500) {
const extraMB = fileSizeMB - 500;
const extraMinutes = Math.ceil(extraMB / 100);
return baseTimeout + extraMinutes * 60000;
}
return baseTimeout;
};
const uploadFile = async (fileUpload: FileUpload) => {
const { file, id } = fileUpload;
@@ -312,12 +324,13 @@ export function UploadFileModal({ isOpen, onClose, onSuccess, currentFolderId }:
folderId: currentFolderId,
});
} else {
const uploadTimeout = calculateUploadTimeout(file.size);
await axios.put(url, file, {
headers: {
"Content-Type": file.type,
},
signal: abortController.signal,
timeout: 300000, // 5 minutes timeout for direct uploads
timeout: uploadTimeout,
maxContentLength: Infinity,
maxBodyLength: Infinity,
onUploadProgress: (progressEvent) => {