mirror of
https://github.com/open-webui/open-webui.git
synced 2026-10-29 06:32:52 +00:00
fix: requests hang or fail with 503 after pages are closed while loading (#32617)
Closing a page while the server was still sending it data (a file's processing status, a chat export) could interrupt a database read halfway. On SQLite the connection used for it was then never given back, and a later unrelated request could hang forever when that connection was finally cleaned up; once enough were lost, every request needing the database waited 30 seconds and failed with a 503. The connection is now kept and rolled back instead of being thrown away inside the interrupted request, and the session is closed once instead of twice, as either alone still lost connections. Closing 600 chat exports and 300 file status streams mid-load on SQLite used to lose 60 (the whole pool in that test) and 56 connections, now none; Postgres lost none before or after. Fixes #32609
This commit is contained in:
parent
9cbd27011b
commit
2355b8a369
1 changed files with 9 additions and 8 deletions
|
|
@ -1,5 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
|
@ -476,6 +477,12 @@ if 'sqlite' in ASYNC_SQLALCHEMY_DATABASE_URL:
|
|||
@event.listens_for(async_engine.sync_engine, 'connect')
|
||||
def _set_sqlite_pragmas(dbapi_connection, connection_record):
|
||||
_apply_sqlite_pragmas(dbapi_connection)
|
||||
|
||||
@event.listens_for(async_engine.sync_engine, 'handle_error')
|
||||
def _keep_connection_on_cancel(context):
|
||||
# invalidating here would close the connection inside the cancelled task, and that close is lost
|
||||
if isinstance(context.original_exception, asyncio.CancelledError):
|
||||
context.is_disconnect = False
|
||||
else:
|
||||
if isinstance(DATABASE_POOL_SIZE, int):
|
||||
if DATABASE_POOL_SIZE > 0:
|
||||
|
|
@ -514,20 +521,14 @@ AsyncSessionLocal = async_sessionmaker(
|
|||
async def get_async_session():
|
||||
"""Async session generator for FastAPI Depends()."""
|
||||
async with AsyncSessionLocal() as db:
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
await db.close()
|
||||
yield db
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def get_async_db():
|
||||
"""Async context manager for use outside of FastAPI dependency injection."""
|
||||
async with AsyncSessionLocal() as db:
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
await db.close()
|
||||
yield db
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue