fix(queue): enqueue 경로 중복 방어 — partial unique index + 중앙 enqueue_stage 함수
기존 UNIQUE(document_id, stage, status)는 pending+processing 동시 존재를 허용해서 stale 복구 시 충돌 발생. 2-layer 방어로 근본 차단: 1) DB: partial unique index uq_queue_active — 활성 행(pending/processing)은 (document_id, stage)당 최대 1개만 허용 2) App: enqueue_stage() 중앙 함수 — INSERT ON CONFLICT DO NOTHING으로 모든 9개 경로의 check-then-insert TOCTOU race 제거 migration 117은 guard check 포함 — 활성 중복이 남아있으면 RAISE EXCEPTION 으로 중단, 수동 정리 유도. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,7 @@ from core.config import settings
|
||||
from core.database import get_session
|
||||
from core.utils import file_hash
|
||||
from models.document import Document
|
||||
from models.queue import ProcessingQueue
|
||||
from models.queue import ProcessingQueue, enqueue_stage
|
||||
from models.user import User
|
||||
|
||||
router = APIRouter()
|
||||
@@ -473,11 +473,7 @@ async def upload_document(
|
||||
await session.flush()
|
||||
|
||||
# 처리 큐 등록
|
||||
session.add(ProcessingQueue(
|
||||
document_id=doc.id,
|
||||
stage="extract",
|
||||
status="pending",
|
||||
))
|
||||
await enqueue_stage(session, doc.id, "extract")
|
||||
await session.commit()
|
||||
|
||||
return DocumentResponse.model_validate(doc)
|
||||
|
||||
+2
-6
@@ -13,7 +13,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from core.auth import get_current_user
|
||||
from core.database import get_session
|
||||
from models.document import Document
|
||||
from models.queue import ProcessingQueue
|
||||
from models.queue import ProcessingQueue, enqueue_stage
|
||||
from models.user import User
|
||||
|
||||
router = APIRouter()
|
||||
@@ -57,11 +57,7 @@ async def _enqueue_ai_stages(session: AsyncSession, document_id: int):
|
||||
)
|
||||
)
|
||||
for stage in stages:
|
||||
session.add(ProcessingQueue(
|
||||
document_id=document_id,
|
||||
stage=stage,
|
||||
status="pending",
|
||||
))
|
||||
await enqueue_stage(session, document_id, stage)
|
||||
|
||||
|
||||
# ─── 스키마 ───
|
||||
|
||||
Reference in New Issue
Block a user