@@ -87,6 +87,10 @@ async def lifespan(app: FastAPI):
8787# sequential prompt processing for in-house LLMs (non-nc_texttotext)
8888llm_lock = threading .Lock ()
8989
90+ # lock to update the sources dict currently being processed
91+ index_lock = threading .Lock ()
92+ _indexing = {}
93+
9094# limit the number of concurrent document parsing
9195doc_parse_semaphore = mp .Semaphore (app_config .doc_parser_worker_limit )
9296
@@ -286,10 +290,25 @@ def _(userId: str = Body(embed=True)):
286290@app .put ('/loadSources' )
287291@enabled_guard (app )
288292def _ (sources : list [UploadFile ]):
293+ global _indexing
294+
289295 if len (sources ) == 0 :
290296 return JSONResponse ('No sources provided' , 400 )
291297
292298 for source in sources :
299+ if not value_of (source .filename ):
300+ return JSONResponse (f'Invalid source filename for: { source .headers .get ("title" )} ' , 400 )
301+
302+ with index_lock :
303+ if source .filename in _indexing :
304+ # this request will be retried by the client
305+ return JSONResponse (
306+ f'Source already being processed: { source .filename } ' ,
307+ 503 ,
308+ headers = {'cc-retry' : 'true' },
309+ )
310+ _indexing [source .filename ] = True
311+
293312 if not (
294313 value_of (source .headers .get ('userIds' ))
295314 and value_of (source .headers .get ('title' ))
@@ -300,13 +319,21 @@ def _(sources: list[UploadFile]):
300319 ):
301320 return JSONResponse (f'Invaild/missing headers for: { source .filename } ' , 400 )
302321
303- if not value_of (source .filename ):
304- return JSONResponse (f'Invalid source filename for: { source .headers .get ("title" )} ' , 400 )
305-
306- doc_parse_semaphore .acquire (block = True , timeout = 29 * 60 ) # ~29 minutes
322+ # wait for 10 minutes before failing the request
323+ semres = doc_parse_semaphore .acquire (block = True , timeout = 10 * 60 )
324+ if not semres :
325+ return JSONResponse (
326+ 'Document parser worker limit reached, try again in some time' ,
327+ 503 ,
328+ headers = {'cc-retry' : 'true' }
329+ )
307330 added_sources = exec_in_proc (target = embed_sources , args = (vectordb_loader , app .extra ['CONFIG' ], sources ))
308331 doc_parse_semaphore .release ()
309332
333+ for source in sources :
334+ with index_lock :
335+ _indexing .pop (source .filename )
336+
310337 if len (added_sources ) != len (sources ):
311338 print (
312339 'Count of newly loaded sources:' , len (added_sources ),
0 commit comments