From d037a6cf8b214e398b23a2f0837f903ae5b59e3e Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Tue, 17 Dec 2024 16:47:32 +0530 Subject: [PATCH] - Do not clear temp files that are locked. - Handle edge cases in sync workspace --- web/core/local-db/storage.sqlite.ts | 6 +-- web/core/local-db/utils/load-workspace.ts | 10 ++--- web/core/local-db/utils/utils.ts | 52 +++++++++++++++++------ web/core/store/user/index.ts | 2 +- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/web/core/local-db/storage.sqlite.ts b/web/core/local-db/storage.sqlite.ts index ed0ceb880df..12f918293cb 100644 --- a/web/core/local-db/storage.sqlite.ts +++ b/web/core/local-db/storage.sqlite.ts @@ -59,10 +59,10 @@ export class Storage { this.workspaceSlug = ""; }; - clearStorage = async () => { + clearStorage = async (force = false) => { try { - await this.db.close(); - await clearOPFS(); + await this.db?.close(); + await clearOPFS(force); this.reset(); } catch (e) { console.error("Error clearing sqlite sync storage", e); diff --git a/web/core/local-db/utils/load-workspace.ts b/web/core/local-db/utils/load-workspace.ts index 42a79f9dd64..0cd4931187b 100644 --- a/web/core/local-db/utils/load-workspace.ts +++ b/web/core/local-db/utils/load-workspace.ts @@ -109,7 +109,7 @@ const syncLabels = async (currentLabels: any) => { const currentIdList = currentLabels.map((label: any) => label.id); const existingLabels = await persistence.db.exec("SELECT id FROM labels;"); - const existingIdList = existingLabels.map((label: any) => label.id); + const existingIdList = existingLabels ? existingLabels.map((label: any) => label.id) : []; const deletedIds = difference(existingIdList, currentIdList); @@ -140,7 +140,7 @@ export const syncIssuesWithDeletedLabels = async (deletedLabelIds: string[]) => const syncModules = async (currentModules: any) => { const currentIdList = currentModules.map((module: any) => module.id); const existingModules = await persistence.db.exec("SELECT id FROM modules;"); - const existingIdList = existingModules.map((module: any) => module.id); + const existingIdList = existingModules ? existingModules.map((module: any) => module.id) : []; const deletedIds = difference(existingIdList, currentIdList); await syncIssuesWithDeletedModules(deletedIds as string[]); }; @@ -167,7 +167,7 @@ export const syncIssuesWithDeletedModules = async (deletedModuleIds: string[]) = const syncCycles = async (currentCycles: any) => { const currentIdList = currentCycles.map((cycle: any) => cycle.id); const existingCycles = await persistence.db.exec("SELECT id FROM cycles;"); - const existingIdList = existingCycles.map((cycle: any) => cycle.id); + const existingIdList = existingCycles ? existingCycles.map((cycle: any) => cycle.id) : []; const deletedIds = difference(existingIdList, currentIdList); await syncIssuesWithDeletedCycles(deletedIds as string[]); }; @@ -194,7 +194,7 @@ export const syncIssuesWithDeletedCycles = async (deletedCycleIds: string[]) => const syncStates = async (currentStates: any) => { const currentIdList = currentStates.map((state: any) => state.id); const existingStates = await persistence.db.exec("SELECT id FROM states;"); - const existingIdList = existingStates.map((state: any) => state.id); + const existingIdList = existingStates ? existingStates.map((state: any) => state.id) : []; const deletedIds = difference(existingIdList, currentIdList); await syncIssuesWithDeletedStates(deletedIds as string[]); }; @@ -221,7 +221,7 @@ export const syncIssuesWithDeletedStates = async (deletedStateIds: string[]) => const syncMembers = async (currentMembers: any) => { const currentIdList = currentMembers.map((member: any) => member.id); const existingMembers = await persistence.db.exec("SELECT id FROM members;"); - const existingIdList = existingMembers.map((member: any) => member.id); + const existingIdList = existingMembers ? existingMembers.map((member: any) => member.id) : []; const deletedIds = difference(existingIdList, currentIdList); await syncIssuesWithDeletedMembers(deletedIds as string[]); }; diff --git a/web/core/local-db/utils/utils.ts b/web/core/local-db/utils/utils.ts index 236d8287200..6cd5f3033c5 100644 --- a/web/core/local-db/utils/utils.ts +++ b/web/core/local-db/utils/utils.ts @@ -160,24 +160,48 @@ const parseSQLite3Error = (error: any) => { return error; }; -export const clearOPFS = async () => { - const storageManager = window.navigator.storage; - const fileSystemDirectoryHandle = await storageManager.getDirectory(); +export const isChrome = () => { const userAgent = navigator.userAgent; - const isChrome = userAgent.includes("Chrome") && !userAgent.includes("Edg") && !userAgent.includes("OPR"); + return userAgent.includes("Chrome") && !userAgent.includes("Edg") && !userAgent.includes("OPR"); +}; + +export const clearOPFS = async (force = false) => { + const storageManager = window.navigator.storage; + const root = await storageManager.getDirectory(); - if (isChrome) { - await (fileSystemDirectoryHandle as any).remove({ recursive: true }); + if (force && isChrome()) { + await (root as any).remove({ recursive: true }); return; } - - const entries = await (fileSystemDirectoryHandle as any).entries(); - for await (const entry of entries) { - const [name] = entry; - try { - await fileSystemDirectoryHandle.removeEntry(name); - } catch (e) { - console.log("Error", e); + // ts-ignore + for await (const entry of root.values()) { + if (entry.kind === "directory" && entry.name.startsWith(".ahp-")) { + // A lock with the same name as the directory protects it from + // being deleted. + + if (force) { + // don't wait for the lock + try { + await root.removeEntry(entry.name, { recursive: true }); + } catch (e) { + console.log(e); + } + } else { + await navigator.locks.request(entry.name, { ifAvailable: true }, async (lock) => { + if (lock) { + log?.(`Deleting temporary directory ${entry.name}`); + try { + await root.removeEntry(entry.name, { recursive: true }); + } catch (e) { + console.log(e); + } + } else { + log?.(`Temporary directory ${entry.name} is in use`); + } + }); + } + } else { + root.removeEntry(entry.name); } } }; diff --git a/web/core/store/user/index.ts b/web/core/store/user/index.ts index eac764a3db3..7c0622ec463 100644 --- a/web/core/store/user/index.ts +++ b/web/core/store/user/index.ts @@ -231,7 +231,7 @@ export class UserStore implements IUserStore { */ signOut = async (): Promise => { await this.authService.signOut(API_BASE_URL); - await persistence.clearStorage(); + await persistence.clearStorage(true); this.store.resetOnSignOut(); };