From 38d403bcc26244e778a6e7a2f75ee39a9ec7ed27 Mon Sep 17 00:00:00 2001
From: Mohamed Bassem <me@mbassem.com>
Date: Sun, 12 Jan 2025 23:47:25 +0000
Subject: fix: Limit concurrency of bulk actions. Fix #773

---
 .../components/dashboard/BulkBookmarksAction.tsx   | 41 +++++++++++++++-------
 1 file changed, 28 insertions(+), 13 deletions(-)

(limited to 'apps/web/components/dashboard/BulkBookmarksAction.tsx')

diff --git a/apps/web/components/dashboard/BulkBookmarksAction.tsx b/apps/web/components/dashboard/BulkBookmarksAction.tsx
index eb0e0cec..9d5ecdbe 100644
--- a/apps/web/components/dashboard/BulkBookmarksAction.tsx
+++ b/apps/web/components/dashboard/BulkBookmarksAction.tsx
@@ -27,12 +27,15 @@ import {
   useRecrawlBookmark,
   useUpdateBookmark,
 } from "@hoarder/shared-react/hooks/bookmarks";
+import { limitConcurrency } from "@hoarder/shared/concurrency";
 import { BookmarkTypes } from "@hoarder/shared/types/bookmarks";
 
 import BulkManageListsModal from "./bookmarks/BulkManageListsModal";
 import BulkTagModal from "./bookmarks/BulkTagModal";
 import { ArchivedActionIcon, FavouritedActionIcon } from "./bookmarks/icons";
 
+const MAX_CONCURRENT_BULK_ACTIONS = 50;
+
 export default function BulkBookmarksAction() {
   const { t } = useTranslation();
   const { selectedBookmarks, isBulkEditEnabled } = useBulkActionsStore();
@@ -100,11 +103,15 @@ export default function BulkBookmarksAction() {
       (item) => item.content.type === BookmarkTypes.LINK,
     );
     await Promise.all(
-      links.map((item) =>
-        recrawlBookmarkMutator.mutateAsync({
-          bookmarkId: item.id,
-          archiveFullPage,
-        }),
+      limitConcurrency(
+        links.map(
+          (item) => () =>
+            recrawlBookmarkMutator.mutateAsync({
+              bookmarkId: item.id,
+              archiveFullPage,
+            }),
+        ),
+        MAX_CONCURRENT_BULK_ACTIONS,
       ),
     );
     toast({
@@ -145,12 +152,16 @@ export default function BulkBookmarksAction() {
     archived,
   }: UpdateBookmarkProps) => {
     await Promise.all(
-      selectedBookmarks.map((item) =>
-        updateBookmarkMutator.mutateAsync({
-          bookmarkId: item.id,
-          favourited,
-          archived,
-        }),
+      limitConcurrency(
+        selectedBookmarks.map(
+          (item) => () =>
+            updateBookmarkMutator.mutateAsync({
+              bookmarkId: item.id,
+              favourited,
+              archived,
+            }),
+        ),
+        MAX_CONCURRENT_BULK_ACTIONS,
       ),
     );
     toast({
@@ -160,8 +171,12 @@ export default function BulkBookmarksAction() {
 
   const deleteBookmarks = async () => {
     await Promise.all(
-      selectedBookmarks.map((item) =>
-        deleteBookmarkMutator.mutateAsync({ bookmarkId: item.id }),
+      limitConcurrency(
+        selectedBookmarks.map(
+          (item) => () =>
+            deleteBookmarkMutator.mutateAsync({ bookmarkId: item.id }),
+        ),
+        MAX_CONCURRENT_BULK_ACTIONS,
       ),
     );
     toast({
-- 
cgit v1.2.3-70-g09d2

