From 31b764f458b52ee6224ab354a50d18b7366a3e62 Mon Sep 17 00:00:00 2001 From: Mathieu Date: Wed, 24 Jun 2026 17:08:32 +0200 Subject: [PATCH] fix: limit concurrent AI background removal to 2 to prevent browser crash Co-Authored-By: Claude Sonnet 4.6 --- src/hooks/useImages.ts | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/hooks/useImages.ts b/src/hooks/useImages.ts index 3a6f79e..877e3ed 100644 --- a/src/hooks/useImages.ts +++ b/src/hooks/useImages.ts @@ -1,7 +1,29 @@ 'use client' -import { useReducer, useCallback } from 'react' +import { useReducer, useCallback, useRef } from 'react' import type { ImageItem, ImageStatus } from '@/types/images' +// File d'attente avec concurrence limitée pour le pipeline IA +const CONCURRENCY = 2 + +function createQueue() { + let running = 0 + const queue: Array<() => Promise> = [] + + function next() { + if (running >= CONCURRENCY || queue.length === 0) return + running++ + const task = queue.shift()! + task().finally(() => { running--; next() }) + } + + return { + enqueue(task: () => Promise) { + queue.push(task) + next() + }, + } +} + // ── Reducer ─────────────────────────────────────────────────────────────────── type Action = @@ -47,6 +69,7 @@ function blobToBase64(blob: Blob): Promise { export function useImages() { const [items, dispatch] = useReducer(reducer, []) + const queueRef = useRef(createQueue()) const update = useCallback((id: string, patch: Partial) => { dispatch({ type: 'UPDATE', id, patch }) @@ -177,7 +200,7 @@ export function useImages() { })) dispatch({ type: 'ADD', items: newItems }) for (const item of newItems) { - runPipeline(item.id, item.originalBlob, item.ref, item.feather, item.rotation, item.alphaThreshold) + queueRef.current.enqueue(() => runPipeline(item.id, item.originalBlob, item.ref, item.feather, item.rotation, item.alphaThreshold)) } } else { const ref = refFromFilename(file.name) @@ -199,7 +222,7 @@ export function useImages() { progress: null, } dispatch({ type: 'ADD', items: [newItem] }) - runPipeline(newItem.id, newItem.originalBlob, newItem.ref, newItem.feather, newItem.rotation, newItem.alphaThreshold) + queueRef.current.enqueue(() => runPipeline(newItem.id, newItem.originalBlob, newItem.ref, newItem.feather, newItem.rotation, newItem.alphaThreshold)) } } },