diff --git a/.env.example b/.env.example index 34f84d4..99232c5 100644 --- a/.env.example +++ b/.env.example @@ -80,6 +80,10 @@ IMPORT_LIBRARY_DIRS= # Heavy compute backend mode for ONNX whisper alignment + PDF layout parsing. # local = run compute in-process (default) # worker = external durable worker mode (requires NATS JetStream-backed compute-worker service) +# Parse progress transport behavior: +# - local mode: in-process memory event bus inside app server +# - worker mode: app proxies compute-worker op events via SSE +# No app-layer NATS configuration is required for parse progress. COMPUTE_MODE=local # Required when COMPUTE_MODE=worker # COMPUTE_WORKER_URL=http://localhost:8081 diff --git a/compute/worker/.env.example b/compute/worker/.env.example index 800dd93..ae593dd 100644 --- a/compute/worker/.env.example +++ b/compute/worker/.env.example @@ -39,6 +39,8 @@ S3_FORCE_PATH_STYLE=true # PDF_LAYOUT_MODEL_BASE_URL=https://huggingface.co/Bei0001/PP-DocLayoutV3-ONNX/resolve/main # COMPUTE_PDF_JOB_ATTEMPTS=1 # COMPUTE_JOBS_STREAM_MAX_BYTES=268435456 +# JetStream stream size limit for op progress events (replay for SSE reconnect) +# COMPUTE_EVENTS_STREAM_MAX_BYTES=134217728 # COMPUTE_JOB_STATES_MAX_BYTES=67108864 # COMPUTE_NATS_REPLICAS=1 # Optional stale window for reusing in-flight opKey entries before forcing a new attempt diff --git a/src/app/(app)/pdf/[id]/usePdfDocument.ts b/src/app/(app)/pdf/[id]/usePdfDocument.ts index fe6101d..4451333 100644 --- a/src/app/(app)/pdf/[id]/usePdfDocument.ts +++ b/src/app/(app)/pdf/[id]/usePdfDocument.ts @@ -216,7 +216,7 @@ export function usePdfDocument(): PdfDocumentState { } }, []); - const startParsedPolling = useCallback((documentId: string, initialStatus: PdfParseStatus | null) => { + const startParsedPolling = useCallback((documentId: string) => { parsePollAbortRef.current?.abort(); parseSseCloseRef.current?.(); parseSseCloseRef.current = null; @@ -244,15 +244,8 @@ export function usePdfDocument(): PdfDocumentState { } }, onError: () => { - // Fall back to parsed polling if browser SSE disconnects. + // EventSource reconnects automatically. Keep stream open. if (controller.signal.aborted) return; - closeSse(); - parseSseCloseRef.current = null; - void fetchParsedDocument(documentId, initialStatus, controller.signal).finally(() => { - if (parsePollAbortRef.current === controller) { - parsePollAbortRef.current = null; - } - }); }, }); parseSseCloseRef.current = closeSse; @@ -464,7 +457,7 @@ export function usePdfDocument(): PdfDocumentState { const initialParseStatus = (meta.parseStatus ?? null) as PdfParseStatus | null; setParseStatus(initialParseStatus); setParseProgress(null); - startParsedPolling(id, initialParseStatus); + startParsedPolling(id); void fetchDocumentSettings(id, controller.signal); } @@ -520,7 +513,7 @@ export function usePdfDocument(): PdfDocumentState { setParsedDocument(null); setParseStatus('pending'); setParseProgress(null); - startParsedPolling(currDocId, 'pending'); + startParsedPolling(currDocId); } catch (error) { console.error('Failed to force PDF reparse:', error); }