@@ -42,16 +42,16 @@ function findSentenceBoundary(text: string, index: number): number {
4242
4343const logger = createLogger ( 'knowledge-base-service:processor' )
4444
45- export async function processDocument ( documentId : string ) {
45+ export async function processDocument ( documentId : string , job ?: { updateProgress : ( progress : number ) => Promise < void > } ) {
4646 const timeoutPromise = new Promise < never > ( ( _ , reject ) => {
4747 setTimeout ( ( ) => {
4848 reject ( new Error ( `Document processing timeout after ${ PROCESSING_CONSTANTS . TIMEOUT_MS / 1000 } seconds` ) )
4949 } , PROCESSING_CONSTANTS . TIMEOUT_MS )
5050 } )
5151
52- try {
52+ try {
5353 await Promise . race ( [
54- processDocumentInternal ( documentId ) ,
54+ processDocumentInternal ( documentId , job ) ,
5555 timeoutPromise ,
5656 ] )
5757 } catch ( error ) {
@@ -79,7 +79,7 @@ export async function processDocument(documentId: string) {
7979 }
8080}
8181
82- async function processDocumentInternal ( documentId : string ) {
82+ async function processDocumentInternal ( documentId : string , job ?: { updateProgress : ( progress : number ) => Promise < void > } ) {
8383 const supabase = getSupabase ( )
8484
8585 await supabase
@@ -268,6 +268,14 @@ async function processDocumentInternal(documentId: string) {
268268 // Move to next window
269269 windowStart = windowEnd
270270
271+ // Update job progress periodically to prevent stall detection
272+ if ( job && windowNumber % 3 === 0 ) {
273+ const progress = Math . min ( 10 + Math . floor ( ( windowStart / textLength ) * 80 ) , 90 )
274+ await job . updateProgress ( progress ) . catch ( ( ) => {
275+ // Ignore progress update errors (job might be completed)
276+ } )
277+ }
278+
271279 // Force GC every few windows for large documents
272280 if ( global . gc && windowNumber % 5 === 0 ) {
273281 global . gc ( )
0 commit comments