fix: limit concurrent AI background removal to 2 to prevent browser crash
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+26
-3
@@ -1,7 +1,29 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import { useReducer, useCallback } from 'react'
|
import { useReducer, useCallback, useRef } from 'react'
|
||||||
import type { ImageItem, ImageStatus } from '@/types/images'
|
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<void>> = []
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
if (running >= CONCURRENCY || queue.length === 0) return
|
||||||
|
running++
|
||||||
|
const task = queue.shift()!
|
||||||
|
task().finally(() => { running--; next() })
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
enqueue(task: () => Promise<void>) {
|
||||||
|
queue.push(task)
|
||||||
|
next()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Reducer ───────────────────────────────────────────────────────────────────
|
// ── Reducer ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
type Action =
|
type Action =
|
||||||
@@ -47,6 +69,7 @@ function blobToBase64(blob: Blob): Promise<string> {
|
|||||||
|
|
||||||
export function useImages() {
|
export function useImages() {
|
||||||
const [items, dispatch] = useReducer(reducer, [])
|
const [items, dispatch] = useReducer(reducer, [])
|
||||||
|
const queueRef = useRef(createQueue())
|
||||||
|
|
||||||
const update = useCallback((id: string, patch: Partial<ImageItem>) => {
|
const update = useCallback((id: string, patch: Partial<ImageItem>) => {
|
||||||
dispatch({ type: 'UPDATE', id, patch })
|
dispatch({ type: 'UPDATE', id, patch })
|
||||||
@@ -177,7 +200,7 @@ export function useImages() {
|
|||||||
}))
|
}))
|
||||||
dispatch({ type: 'ADD', items: newItems })
|
dispatch({ type: 'ADD', items: newItems })
|
||||||
for (const item of 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 {
|
} else {
|
||||||
const ref = refFromFilename(file.name)
|
const ref = refFromFilename(file.name)
|
||||||
@@ -199,7 +222,7 @@ export function useImages() {
|
|||||||
progress: null,
|
progress: null,
|
||||||
}
|
}
|
||||||
dispatch({ type: 'ADD', items: [newItem] })
|
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user