From 5ee14090cc608b6369a0ca7a4e5af1c027cb34cd Mon Sep 17 00:00:00 2001 From: Alexey Safronov Date: Wed, 14 Jun 2023 20:55:15 +0400 Subject: [PATCH] Web: fix upload call stack hell --- packages/client/package.json | 1 + packages/client/src/store/FilesStore.js | 78 ++++++++++++++------ packages/client/src/store/UploadDataStore.js | 3 +- yarn.lock | 8 ++ 4 files changed, 67 insertions(+), 23 deletions(-) diff --git a/packages/client/package.json b/packages/client/package.json index 8b50f191e2..da19486031 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -46,6 +46,7 @@ "file-saver": "^2.0.5", "firebase": "^8.10.0", "hex-to-rgba": "^2.0.1", + "queue-promise": "2.2.1", "react-avatar-editor": "^13.0.0", "react-colorful": "^5.5.1", "react-hotkeys-hook": "^3.4.4", diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index 7e2c470926..601625862a 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -28,6 +28,7 @@ import { isDesktop } from "@docspace/components/utils/device"; import { getContextMenuKeysByType } from "SRC_DIR/helpers/plugins"; import { PluginContextMenuItemType } from "SRC_DIR/helpers/plugins/constants"; import debounce from "lodash.debounce"; +import Queue from "queue-promise"; const { FilesFilter, RoomsFilter } = api; const storageViewAs = localStorage.getItem("viewAs"); @@ -129,6 +130,11 @@ class FilesStore { highlightFile = {}; thumbnails = new Set(); movingInProgress = false; + createNewFilesQueue = new Queue({ + concurrent: 5, + interval: 500, + start: true, + }); constructor( authStore, @@ -272,8 +278,43 @@ class FilesStore { this.createThumbnail(this.files[foundIndex]); }); + + this.createNewFilesQueue.on("resolve", this.onResolveNewFile); } + onResolveNewFile = (fileInfo) => { + if (!fileInfo) return; + + //console.log("onResolveNewFiles", { fileInfo }); + + if (this.files.findIndex((x) => x.id === fileInfo.id) > -1) return; + + console.log("[WS] create new file", { fileInfo }); + + const newFiles = [fileInfo, ...this.files]; + + if ( + newFiles.length > this.filter.pageCount && + this.authStore.settingsStore.withPaging + ) { + newFiles.pop(); // Remove last + } + + const newFilter = this.filter; + newFilter.total += 1; + + runInAction(() => { + this.setFilter(newFilter); + this.setFiles(newFiles); + }); + + this.debouncefetchTreeFolders(); + }; + + debouncefetchTreeFolders = debounce(() => { + this.treeFoldersStore.fetchTreeFolders(); + }, 1000); + debounceRemoveFiles = debounce(() => { this.removeFiles(this.tempActionFilesIds); }, 1000); @@ -296,34 +337,29 @@ class FilesStore { //To update a file version if (foundIndex > -1 && !this.authStore.settingsStore.withPaging) { - this.getFileInfo(file.id); + //this.getFileInfo(file.id); this.checkSelection(file); } if (foundIndex > -1) return; - const fileInfo = await api.files.getFileInfo(file.id); + setTimeout(() => { + const foundIndex = this.files.findIndex((x) => x.id === file.id); + if (foundIndex > -1) { + //console.log("Skip in timeout"); + return null; + } - if (this.files.findIndex((x) => x.id === opt?.id) > -1) return; - console.log("[WS] create new file", fileInfo.id, fileInfo.title); + this.createNewFilesQueue.enqueue(() => { + const foundIndex = this.files.findIndex((x) => x.id === file.id); + if (foundIndex > -1) { + //console.log("Skip in queue"); + return null; + } - const newFiles = [fileInfo, ...this.files]; - - if ( - newFiles.length > this.filter.pageCount && - this.authStore.settingsStore.withPaging - ) { - newFiles.pop(); // Remove last - } - - const newFilter = this.filter; - newFilter.total += 1; - - runInAction(() => { - this.setFilter(newFilter); - this.setFiles(newFiles); - this.treeFoldersStore.fetchTreeFolders(); - }); + return api.files.getFileInfo(file.id); + }); + }, 300); } else if (opt?.type === "folder" && opt?.id) { const foundIndex = this.folders.findIndex((x) => x.id === opt?.id); diff --git a/packages/client/src/store/UploadDataStore.js b/packages/client/src/store/UploadDataStore.js index 21123866ce..3cd0fc8403 100644 --- a/packages/client/src/store/UploadDataStore.js +++ b/packages/client/src/store/UploadDataStore.js @@ -906,7 +906,7 @@ class UploadDataStore { return Promise.reject(res.data.message); } - const { uploaded, id: fileId } = res.data.data; + const { uploaded, id: fileId, file: fileInfo } = res.data.data; let uploadedSize, newPercent; @@ -947,7 +947,6 @@ class UploadDataStore { }); if (uploaded) { - const fileInfo = await getFileInfo(fileId); runInAction(() => { this.files[indexOfFile].action = "uploaded"; this.files[indexOfFile].fileId = fileId; diff --git a/yarn.lock b/yarn.lock index 5c3ad3d5ee..b9a55d55be 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3031,6 +3031,7 @@ __metadata: html-webpack-plugin: 5.3.2 json-loader: ^0.5.7 playwright: ^1.18.1 + queue-promise: 2.2.1 react-avatar-editor: ^13.0.0 react-colorful: ^5.5.1 react-hotkeys-hook: ^3.4.4 @@ -20810,6 +20811,13 @@ __metadata: languageName: node linkType: hard +"queue-promise@npm:2.2.1": + version: 2.2.1 + resolution: "queue-promise@npm:2.2.1" + checksum: 139c1844225580545a94c5a234fcde33e47941f473525bb0df3dacbdd55724993754f048c25c3a8b98961cd84221913b633397383ef8bc92476237d0dca6d721 + languageName: node + linkType: hard + "raf@npm:^3.1.0, raf@npm:^3.4.1": version: 3.4.1 resolution: "raf@npm:3.4.1"