feat(admin): шкала загрузки источников, отладка и загрузка работ в корпус
Заливка корпуса была чёрным ящиком: у источника только last_status (idle/running/done/error), без «сколько из скольки», без причины падения и без способа остановить начатое. Теперь каждый запуск создаёт строку parse_runs, куда воркер раз в ~2с пишет стадию, счётчики и журнал событий. Админка: - шкала загрузки у каждого источника (0→50% выборка, 50→100% индексация), раскрытая строка — журнал прогона по шагам с таймингами; - «Запустить всё» / «Остановить всё» и остановка по одному источнику (кооперативная отмена: воркер останавливается сам, не рвя запись в базу); - пакетное добавление источников (тип + список тем), тип pmc в форме; - загрузка PDF/DOCX/TXT прямо в базу сравнения (index.ingest_upload); - страница «Отладка»: воркеры Celery и их текущие таски, очереди RabbitMQ, покрытие корпуса эмбеддингами, зависшие и упавшие прогоны, конфиг бэкендов. Защита от краш-лупа по consumer_timeout RabbitMQ (docs/DR-HA.md §6), без неё массовый запуск 170+ источников гарантированно ронял воркер: - PARSER_TIME_BUDGET_S (1500с) — прогон закругляется сам и помечается partial; - worker_prefetch_multiplier=1 — таймаут считается от ДОСТАВКИ сообщения, и с дефолтным префетчем очередь долгих run_parser убивала канал на задачах, которые ещё не начинались. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -66,8 +66,22 @@ Redis у нас — кэш/rate-limits/LSH-индекс (префикс `antipla
|
||||
(`restart: unless-stopped`) поднимает его заново, недоставленное сообщение
|
||||
передоставляется — и цикл повторяется бесконечно, монополизируя весь пул воркера
|
||||
(было и на `worker-indexer` из-за backoff `scripts/parsers/openalex.py`, и на
|
||||
`worker-gpu` из-за зависшей Ollama на embedding-gpu). Текущая митигация — держать
|
||||
retry-бэкоффы заведомо короче 1800с (пример: `MAX_RATE_LIMIT_RETRIES` в
|
||||
`openalex.py`). Более глубокий фикс — поднять `consumer_timeout` на самом RabbitMQ
|
||||
(доступа для этого пока не заводили) — актуально при добавлении любых новых
|
||||
долгих retry-циклов в Celery-тасках.
|
||||
`worker-gpu` из-за зависшей Ollama на embedding-gpu).
|
||||
|
||||
Митигации (2026-08-27, сделано для `worker-indexer`):
|
||||
|
||||
1. **Бюджет времени прогона** — `PARSER_TIME_BUDGET_S` (1500с) в
|
||||
`worker-indexer/app/config.py`: `index.run_parser` сам останавливается раньше
|
||||
дедлайна и помечает прогон `partial` вместо того, чтобы довести воркер до
|
||||
падения. Остаток дозаливается повторным запуском источника.
|
||||
2. **`worker_prefetch_multiplier=1`** (`worker-indexer/app/celery_app.py`) —
|
||||
ключевое при массовой заливке. Таймаут отсчитывается от **доставки**
|
||||
сообщения, а не от начала выполнения: с дефолтным префетчем (4×concurrency)
|
||||
сотни поставленных в очередь долгих `run_parser` висят unacked и убивают
|
||||
канал на задачах, которые ещё даже не начинались.
|
||||
3. Retry-бэкоффы держим заведомо короче 1800с (`MAX_RATE_LIMIT_RETRIES` в
|
||||
`openalex.py`).
|
||||
|
||||
`worker-gpu` этих защит пока не имеет (там нет своих долгих retry-циклов, но
|
||||
есть зависание внешней Ollama — см. выше). Более глубокий общий фикс — поднять
|
||||
`consumer_timeout` на самом RabbitMQ (доступа для этого пока не заводили).
|
||||
|
||||
Reference in New Issue
Block a user