fix(indexer): гонка дублей ext_id (IntegrityError→duplicate) + откат Dockerfile

- add_document: параллельные воркеры проходили проверку existing и оба
  вставляли один ext_id → IntegrityError в логах. Теперь ловим её, откатываем
  и возвращаем duplicate — чисто, без шумных ошибок.
- Dockerfile: откат --timeout/--retries (он инвалидировал кэш pip-слоя, а
  толку от него при недоступном pypi нет). Устойчивость сборки решать зеркалом
  когда появится рабочее.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jze9
2026-08-07 16:05:42 +05:00
parent c4596f2c3a
commit 52e5550f91
2 changed files with 12 additions and 3 deletions

View File

@@ -13,8 +13,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
WORKDIR /app WORKDIR /app
COPY requirements.txt . COPY requirements.txt .
# --timeout/--retries: канал до pypi медленный и флоки, без этого сборка падает RUN pip install --no-cache-dir -r requirements.txt
RUN pip install --no-cache-dir --timeout 120 --retries 10 -r requirements.txt
COPY . . COPY . .

View File

@@ -7,6 +7,7 @@ from typing import Any
from celery.utils.log import get_task_logger from celery.utils.log import get_task_logger
from sqlalchemy import func, select from sqlalchemy import func, select
from sqlalchemy.exc import IntegrityError
from app.algorithms.minhash import add_to_lsh, find_similar from app.algorithms.minhash import add_to_lsh, find_similar
from app.algorithms.winnowing import winnow from app.algorithms.winnowing import winnow
@@ -299,7 +300,16 @@ def add_document(doc_data: dict[str, Any], dispatch_embed: bool = True) -> dict[
doc = Document(**doc_kwargs) doc = Document(**doc_kwargs)
session.add(doc) session.add(doc)
try:
session.flush() session.flush()
except IntegrityError:
# Гонка: другой воркер параллельно вставил этот ext_id между нашей
# проверкой existing и flush. Уникальный индекс отработал — это дубль.
session.rollback()
existing = session.execute(
select(Document).where(Document.ext_id == ext_id)
).scalar_one_or_none()
return {"status": "duplicate", "doc_id": existing.id if existing else None}
doc_id = doc.id doc_id = doc.id
# Вычислить fingerprints # Вычислить fingerprints