refactor(ops): массовая заливка — в общий конвейер вместо отдельных скриптов
Заливку Википедии и PMC я сделал отдельными скриптами мимо существующей инфраструктуры: запуск руками через ssh, состояние в файле в /tmp, никакой видимости. Результат предсказуем — за неделю обе умерли молча (обрыв базы на 20 008 статьях из 2 млн и таймаут сети на 85 тыс. из 100 тыс.), прогресс потерялся, а узнали мы об этом через неделю. При том что рядом лежит готовый механизм: parse_sources, прогоны со шкалой, журнал, кнопки, ретраи Celery. Теперь это обычные типы источника — wikipedia_ru и pmc_bulk: - заводятся и запускаются из админки, как OpenAlex или КиберЛенинка; - показывают ту же шкалу, журнал и кнопку остановки; - падение воркера больше не теряет прогресс: позиция продолжения хранится в parse_sources.resume_token (номер статьи в дампе / токен страницы бакета), повторный запуск берёт следующую порцию; - укладываются в бюджет времени таска — заливка идёт порциями, а не одним многосуточным процессом. Чего не хватало конвейеру для миллионов и что добавлено: - парсеры отдают генератор, а не список: 2 млн статей в память не влезают; - app/bulk_writer.py — запись пачками через COPY (21 тыс. строк/с против 6.7 тыс. построчно) с переподключением к базе при обрыве; - эмбеддинги при массовой заливке не диспатчатся: они на порядок медленнее и стали бы узким местом, вектора досчитываются отдельно (reembed_missing.py). scripts/ops/bulk_ingest_*.py удалены — их работу делает конвейер. Проверено на проде: оба парсера отдают документы, прогон через run_parser завершается штатно, позиция продолжения сдвигается (300 → 600), повторный запуск продолжает с неё. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -120,7 +120,9 @@ class ParseRunDetail(ParseRunResponse):
|
||||
|
||||
# ─── Источники парсинга ───────────────────────────────────────────────────────
|
||||
class ParseSourceCreate(BaseModel):
|
||||
source_type: str = Field(description="openalex / cyberleninka / arxiv / pmc")
|
||||
source_type: str = Field(
|
||||
description="openalex / cyberleninka / arxiv / pmc / wikipedia_ru / pmc_bulk"
|
||||
)
|
||||
name: str = Field(min_length=1, max_length=255)
|
||||
query: str | None = None
|
||||
lang: str | None = None
|
||||
@@ -164,7 +166,9 @@ class ParseSourceResponse(BaseModel):
|
||||
class ParseSourceBulkCreate(BaseModel):
|
||||
"""Пакетное добавление: один тип/лимит, много запросов (по строке на тему)."""
|
||||
|
||||
source_type: str = Field(description="openalex / cyberleninka / arxiv / pmc")
|
||||
source_type: str = Field(
|
||||
description="openalex / cyberleninka / arxiv / pmc / wikipedia_ru / pmc_bulk"
|
||||
)
|
||||
queries: list[str] = Field(min_length=1, max_length=500)
|
||||
name_prefix: str = ""
|
||||
lang: str | None = None
|
||||
|
||||
Reference in New Issue
Block a user