fix(audit): run_in_threadpool для write_audit_row в async middleware (#1202) #1252

Merged
bot-backend merged 1 commit from fix/audit-middleware-run-in-threadpool into main 2026-06-13 05:24:40 +00:00

View file

@ -37,6 +37,7 @@ import re
from collections.abc import Awaitable, Callable from collections.abc import Awaitable, Callable
from fastapi import Request from fastapi import Request
from fastapi.concurrency import run_in_threadpool
from fastapi.responses import Response from fastapi.responses import Response
from sqlalchemy import text from sqlalchemy import text
@ -171,10 +172,16 @@ async def audit_log_middleware(
# но если мы тут — нечего атрибутировать, аудит пропускаем. # но если мы тут — нечего атрибутировать, аудит пропускаем.
return response return response
# Write после готового response — off the critical path. Любой сбой внутри # Write после готового response — off the critical path для САМОГО клиента
# write_audit_row проглатывается там же; здесь дополнительная страховка. # (response уже отдан выше), но БЛОКИРУЕТ event loop пока идёт sync DB
# round-trip (SessionLocal/execute/commit). Это останавливает ВСЕ другие
# запросы на loop'е до завершения insert'аа при исчерпании connection
# pool checkout ждёт `pool_timeout=30s` НА loop'е, замораживая весь API
# включая /health (#1202). Выполняем write в threadpool через
# `run_in_threadpool` — sync IO в worker-потоке, event loop свободен.
try: try:
write_audit_row( await run_in_threadpool(
write_audit_row,
username=username, username=username,
action=action, action=action,
method=request.method, method=request.method,