fix(db): CRITICAL - prevent pool exhaustion in memory /reset (#20580)
Remove Depends(get_session) from POST /reset to prevent catastrophic connection pool exhaustion. This endpoint was holding a SINGLE database connection while executing N PARALLEL embedding API calls via asyncio.gather(). For a user with 100 memories, this meant one connection blocked for potentially MINUTES (100 calls * 1-5 seconds each, even in parallel due to rate limits). A single user triggering /reset could completely starve the connection pool, causing QueuePool timeout errors across the entire application. The Memories.get_memories_by_user_id() function now manages its own short-lived session, releasing the connection immediately before the massive parallel embedding operation begins.
This commit is contained in:
@@ -157,8 +157,15 @@ async def query_memory(
|
||||
async def reset_memory_from_vector_db(
|
||||
request: Request,
|
||||
user=Depends(get_verified_user),
|
||||
db: Session = Depends(get_session),
|
||||
):
|
||||
"""Reset user's memory vector embeddings.
|
||||
|
||||
CRITICAL: We intentionally do NOT use Depends(get_session) here.
|
||||
This endpoint generates embeddings for ALL user memories in parallel using
|
||||
asyncio.gather(). A user with 100 memories would trigger 100 embedding API
|
||||
calls simultaneously. With a session held, this could block a connection
|
||||
for MINUTES, completely exhausting the connection pool.
|
||||
"""
|
||||
if not request.app.state.config.ENABLE_MEMORIES:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
@@ -175,7 +182,7 @@ async def reset_memory_from_vector_db(
|
||||
|
||||
VECTOR_DB_CLIENT.delete_collection(f"user-memory-{user.id}")
|
||||
|
||||
memories = Memories.get_memories_by_user_id(user.id, db=db)
|
||||
memories = Memories.get_memories_by_user_id(user.id)
|
||||
|
||||
# Generate vectors in parallel
|
||||
vectors = await asyncio.gather(
|
||||
|
||||
Reference in New Issue
Block a user