Manav Rathi před 1 rokem
rodič
revize
0e9703f770
1 změnil soubory, kde provedl 47 přidání a 81 odebrání
  1. 47 81
      web/apps/photos/src/services/watch.ts

+ 47 - 81
web/apps/photos/src/services/watch.ts

@@ -39,8 +39,16 @@ class FolderWatcher {
     private currentEvent: WatchEvent;
     // TODO(MR): dedup if possible
     private isEventRunning: boolean = false;
+    /**
+     * If the file system directory corresponding to the (root) folder path of a
+     * folder watch is deleted on disk, we note down that in this queue so that
+     * we can ignore any file system events that come for it next.
+     *
+     * TODO (MR): is this really even coming into play? the mappings are
+     * pre-checked first.
+     */
+    private deletedFolderPaths: string[] = [];
     private currentlySyncedMapping: FolderWatch;
-    private trashingDirQueue: string[] = [];
     private filePathToUploadedFileIDMap = new Map<string, EncryptedEnteFile>();
     private unUploadableFilePaths = new Set<string>();
     private setElectronFiles: (files: ElectronFile[]) => void;
@@ -139,12 +147,11 @@ class FolderWatcher {
 
     private async syncWithDisk() {
         try {
-            const electron = ensureElectron();
-            const mappings = await electron.getWatchMappings();
-            if (!mappings) return;
+            const watches = await this.getWatches();
+            if (!watches) return;
 
             this.eventQueue = [];
-            const { events } = await deduceEvents(mappings);
+            const events = await deduceEvents(watches);
             log.info(`Folder watch deduced ${events.length} events`);
             this.eventQueue = this.eventQueue.concat(events);
 
@@ -160,22 +167,40 @@ class FolderWatcher {
         this.debouncedRunNextEvent();
     }
 
-    async pushTrashedDir(path: string) {
-        this.trashingDirQueue.push(path);
-    }
-
     private registerListeners() {
-        const watch = ensureElectron().watcher;
+        const watch = ensureElectron().watch;
 
         // [Note: File renames during folder watch]
         //
         // Renames come as two file system events - an `onAddFile` + an
         // `onRemoveFile` - in an arbitrary order.
-        watch.onAddFile(
-            diskFileAddedCallback,
-            diskFileRemovedCallback,
-            diskFolderRemovedCallback,
-        );
+
+        watch.onAddFile((path: string, watch: FolderWatch) => {
+            this.pushEvent({
+                action: "upload",
+                collectionName: collectionNameForPath(path, watch),
+                folderPath: watch.folderPath,
+                filePath: path,
+            });
+        });
+
+        watch.onRemoveFile((path: string, watch: FolderWatch) => {
+            this.pushEvent({
+                action: "trash",
+                collectionName: collectionNameForPath(path, watch),
+                folderPath: watch.folderPath,
+                filePath: path,
+            });
+        });
+
+        watch.onRemoveDir((path: string, watch: FolderWatch) => {
+            if (path == watch.folderPath) {
+                log.info(
+                    `Received file system delete event for a watched folder at ${path}`,
+                );
+                this.deletedFolderPaths.push(path);
+            }
+        });
     }
 
     private async runNextEvent() {
@@ -446,7 +471,7 @@ class FolderWatcher {
 
     private async processTrashEvent() {
         try {
-            if (this.checkAndIgnoreIfFileEventsFromTrashedDir()) {
+            if (this.pruneFileEventsFromDeletedFolderPaths()) {
                 return;
             }
 
@@ -502,19 +527,14 @@ class FolderWatcher {
         }
     }
 
-    private checkAndIgnoreIfFileEventsFromTrashedDir() {
-        if (this.trashingDirQueue.length !== 0) {
-            this.ignoreFileEventsFromTrashedDir(this.trashingDirQueue[0]);
-            this.trashingDirQueue.shift();
-            return true;
-        }
-        return false;
-    }
+    private pruneFileEventsFromDeletedFolderPaths() {
+        const deletedFolderPath = this.deletedFolderPaths.shift();
+        if (!deletedFolderPath) return false;
 
-    private ignoreFileEventsFromTrashedDir(trashingDir: string) {
-        this.eventQueue = this.eventQueue.filter((event) =>
-            event.paths.every((path) => !path.startsWith(trashingDir)),
+        this.eventQueue = this.eventQueue.filter(
+            (event) => !event.filePath.startsWith(deletedFolderPath),
         );
+        return true;
     }
 
     async getCollectionNameAndFolderPath(filePath: string) {
@@ -594,60 +614,6 @@ interface WatchEvent {
     filePath: string;
 }
 
-const onAddFile = async (path: string) => {
-    const collectionNameAndFolderPath =
-        await watcher.getCollectionNameAndFolderPath(path);
-
-    if (!collectionNameAndFolderPath) {
-        return;
-    }
-
-    const { collectionName, folderPath } = collectionNameAndFolderPath;
-
-    watcher.pushEvent({
-        action: "upload",
-        collectionName,
-        folderPath,
-        path: file.path,
-    });
-};
-
-async function diskFileRemovedCallback(filePath: string) {
-    const collectionNameAndFolderPath =
-        await watcher.getCollectionNameAndFolderPath(filePath);
-
-    if (!collectionNameAndFolderPath) {
-        return;
-    }
-
-    const { collectionName, folderPath } = collectionNameAndFolderPath;
-
-    const event: EventQueueItem = {
-        type: "trash",
-        collectionName,
-        folderPath,
-        path: filePath,
-    };
-    watcher.pushEvent(event);
-}
-
-async function diskFolderRemovedCallback(folderPath: string) {
-    try {
-        const mappings = await watcher.getWatchMappings();
-        const mapping = mappings.find(
-            (mapping) => mapping.folderPath === folderPath,
-        );
-        if (!mapping) {
-            log.info(`folder not found in mappings, ${folderPath}`);
-            throw Error(`Watch mapping not found`);
-        }
-        watcher.pushTrashedDir(folderPath);
-        log.info(`added trashedDir, ${folderPath}`);
-    } catch (e) {
-        log.error("error while calling diskFolderRemovedCallback", e);
-    }
-}
-
 export function getValidFilesToUpload(
     files: ElectronFile[],
     mapping: FolderWatch,