Skip to content

Commit

Permalink
[ui-storagebrowser] fixes chunk upload for new storage browser (#3977)
Browse files Browse the repository at this point in the history
  • Loading branch information
ramprasadagarwal authored and Mohammed Tabraiz committed Jan 31, 2025
1 parent fb2ac48 commit 9edc756
Showing 1 changed file with 55 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,34 @@ const useChunkUpload = ({
}: ChunkUploadOptions): UseUploadQueueResponse => {
const config = getLastKnownConfig();
const chunkSize = config?.storage_browser?.file_upload_chunk_size ?? DEFAULT_CHUNK_SIZE;
const [pendingItems, setPendingItems] = useState<UploadItem[]>([]);
const [processingItem, setProcessingItem] = useState<UploadItem>();
const [pendingUploadItems, setPendingUploadItems] = useState<UploadItem[]>([]);
const [awaitingStatusItems, setAwaitingStatusItems] = useState<UploadItem[]>([]);

const onError = () => {
if (processingItem) {
onStatusUpdate(processingItem, FileUploadStatus.Failed);
setProcessingItem(undefined);
}
};

const onSuccess = (item: UploadItem) => () => {
setAwaitingStatusItems(prev => [...prev, item]);
setProcessingItem(undefined);
};

const { save } = useSaveData(undefined, {
postOptions: {
qsEncodeData: false,
headers: {
'Content-Type': 'multipart/form-data'
}
}
headers: { 'Content-Type': 'multipart/form-data' }
},
onError
});

const updateItemStatus = (serverResponse: TaskServerResponse[]) => {
const statusMap = getStatusHashMap(serverResponse);

const remainingItems = pendingItems.filter(item => {
const remainingItems = awaitingStatusItems.filter(item => {
const status = statusMap[item.uuid];
if (status === TaskStatus.Success || status === TaskStatus.Failure) {
const ItemStatus =
Expand All @@ -84,14 +97,14 @@ const useChunkUpload = ({
if (remainingItems.length === 0) {
onComplete();
}
setPendingItems(remainingItems);
setAwaitingStatusItems(remainingItems);
};

const { data: tasksStatus } = useLoadData<TaskServerResponse[]>(
'/desktop/api2/taskserver/get_taskserver_tasks/',
{
pollInterval: pendingItems.length ? 5000 : undefined,
skip: !pendingItems.length
pollInterval: awaitingStatusItems.length ? 5000 : undefined,
skip: !awaitingStatusItems.length
}
);

Expand All @@ -101,38 +114,36 @@ const useChunkUpload = ({
}
}, [tasksStatus]);

const addItemToPending = (item: UploadItem) => {
setPendingItems(prev => [...prev, item]);
};

const onChunksUploadComplete = async (item: UploadItem) => {
const { url, payload } = getChunksCompletePayload(item, chunkSize);
return save(payload, {
url,
onSuccess: () => addItemToPending(item)
});
const onChunksUploadComplete = async () => {
if (processingItem) {
const { url, payload } = getChunksCompletePayload(processingItem, chunkSize);
return save(payload, {
url,
onSuccess: onSuccess(processingItem)
});
}
};

const uploadChunk = async (chunkItem: UploadChunkItem) => {
const { url, payload } = getChunkItemPayload(chunkItem, chunkSize);
return save(payload, { url });
};

const { enqueueAsync } = useQueueProcessor<UploadChunkItem>(uploadChunk, {
concurrentProcess
const { enqueue } = useQueueProcessor<UploadChunkItem>(uploadChunk, {
concurrentProcess,
onSuccess: onChunksUploadComplete
});

const uploadItemInChunks = async (item: UploadItem) => {
const uploadItemInChunks = (item: UploadItem) => {
const chunks = createChunks(item, chunkSize);
await enqueueAsync(chunks);
return onChunksUploadComplete(item);
return enqueue(chunks);
};

const uploadItemInSingleChunk = (item: UploadItem) => {
const uploadItemInSingleChunk = async (item: UploadItem) => {
const { url, payload } = getChunkSinglePayload(item, chunkSize);
return save(payload, {
url,
onSuccess: () => addItemToPending(item)
onSuccess: onSuccess(item)
});
};

Expand All @@ -158,15 +169,25 @@ const useChunkUpload = ({
return uploadItemInChunks(item);
};

const {
enqueue: addFiles,
dequeue: removeFile,
isLoading
} = useQueueProcessor<UploadItem>(uploadItem, {
concurrentProcess: 1 // This value must be 1 always
});
const addFiles = (newItems: UploadItem[]) => {
setPendingUploadItems(prev => [...prev, ...newItems]);
};

const removeFile = (item: UploadItem) => {
setPendingUploadItems(prev => prev.filter(i => i.uuid !== item.uuid));
};

useEffect(() => {
// Ensures one file is broken down in chunks and uploaded to the server
if (!processingItem && pendingUploadItems.length) {
const item = pendingUploadItems[0];
setProcessingItem(item);
setPendingUploadItems(prev => prev.slice(1));
uploadItem(item);
}
}, [pendingUploadItems, processingItem]);

return { addFiles, removeFile, isLoading };
return { addFiles, removeFile, isLoading: !!processingItem || !!pendingUploadItems.length };
};

export default useChunkUpload;

0 comments on commit 9edc756

Please sign in to comment.