Fix: Ensure Database Consistency on External Image Deletion Events#520
Conversation
Enhances logic to better identify and handle deletions of watched folders, ensuring that image deletions within these folders also trigger appropriate sync actions.
WalkthroughAdds explicit handling for deletions of watched folders in watcher_util_handle_file_changes: flags such deletions, queues their IDs for a delete-folders API call, skips closest-parent calculation and normal sync, and may trigger a watcher restart. Non-deleted changes continue using closest watched parent resolution and sync API calls. Comments were clarified. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant FS as File System
participant W as watcher_util_handle_file_changes
participant S as Sync API
participant D as Delete-Folders API
participant R as Watcher Controller
FS->>W: Change event (add/modify/delete, path)
alt Deleted AND path is a watched folder
note over W: Set is_deleted_watched_folder = true<br/>Collect folder ID
W->>D: deleteFolders(folderIds)
alt Requires restart
D-->>W: Deleted
W->>R: restartWatcher()
else No restart
D-->>W: Deleted
end
else Not a watched-folder deletion
note over W: Resolve closest watched parent folder
W->>S: syncFolder(parentFolderId, path)
S-->>W: Sync triggered
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
sync-microservice/app/utils/watcher.py (1)
78-83: Don’t restart the watcher from inside the watcher thread (self-join hazard).
watcher_util_restart_folder_watcher()callswatcher_util_stop_folder_watcher(), which.join()swatcher_thread. If invoked from the watcher thread, this can raise a RuntimeError and/or deadlock. Restart asynchronously from a separate thread, and (bonus) dedupe folder IDs before calling the delete API.Apply this diff:
- if deleted_folder_ids: - print(f"Calling delete API for {len(deleted_folder_ids)} deleted folders") - watcher_util_call_delete_folders_api(deleted_folder_ids) - watcher_util_restart_folder_watcher() + if deleted_folder_ids: + unique_ids = list(dict.fromkeys(deleted_folder_ids)) + print(f"Calling delete API for {len(unique_ids)} deleted folders") + watcher_util_call_delete_folders_api(unique_ids) + # Restart asynchronously to avoid joining the current watcher thread. + threading.Thread( + target=watcher_util_restart_folder_watcher, daemon=True + ).start()
🧹 Nitpick comments (3)
sync-microservice/app/utils/watcher.py (3)
63-65: Comment/behavior mismatch: this syncs on any file deletion, not just images.If the intent is to limit sync-on-deletion to image files, gate it explicitly; otherwise, update the comment.
Example gating:
def _is_image_file(path: str) -> bool: return os.path.splitext(path)[1].lower() in { ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".tiff", ".svg", ".heic" } # ... if not is_deleted_watched_folder and (change != Change.deleted or _is_image_file(file_path)): # proceed to find closest parent + sync
116-116: Remove noisy debug print in hot path.
print("best match: ", best_match)will spam logs on every event. Drop it or lower to a debug logger.
19-37: Use the existingfolder_id_mapfor O(1) lookups.
watcher_util_get_folder_id_if_watchedcurrently linearly scanswatched_folders. Preferfolder_id_map.get(normalized_path)(ensure keys are normalized consistently when populating).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
sync-microservice/app/utils/watcher.py(1 hunks)
🔇 Additional comments (1)
sync-microservice/app/utils/watcher.py (1)
185-185: Confirmrecursive=Falsemeets the deletion-sync requirement.If images can live in subfolders of watched folders, you likely want
recursive=Trueto see those deletions.
Fixes : #517
This pull request improves the logic for handling file change events in the
watcher_util_handle_file_changesfunction. The main enhancement is to ensure that deletions of image files within watched folders are correctly processed, and that deletions of watched folders themselves are handled distinctly. This results in more accurate syncing behavior when files or folders are deleted.File change handling improvements:
Summary by CodeRabbit
Bug Fixes
Documentation