Стадия 1 — устранение зависаний: таймауты на все TG RPC + починка фонового воркера #1
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Цель
Убрать главный источник полных зависаний приложения: Telegram RPC без таймаутов, удерживающие глобальный throttle-гейт (
tg_throttle, concurrency=1), и молчаливую смерть фонового воркера загрузок.Полный план: plans/2026-07-05-stability-fix-plan.md
Контекст (что чиним)
get_chat_history/get_chatподtg_rpc()держит единственный пермит навсегда → все RSS/HTML-запросы виснут (tg_cache.py:142-144, 216-217).background_download_worker:task_done()вfinallyвызывается даже когдаget()не вернул элемент →ValueError→ воркер умирает молча (api_server.py:620-637). Дальше очередь (maxsize=100) забивается,await download_queue.put()блокируется навсегда (except QueueFull— мёртвый код:await put()его не бросает) → встаёт и уборка кэша.Задачи
tg_rpc_timeout(envTG_RPC_TIMEOUT, default 60)cached_get_chat_history: собрать итерацию в корутину, обернуть вasyncio.wait_forвнутриasync with tg_rpc()cached_get_chat:wait_forвокругclient.get_chat_reply_enrichment(rss_generator.py:505): добавитьtg_rpc()+wait_forPostParser.get_post(post_parser.py:98):wait_for(30); удалитьprint()(строка 95)/health(api_server.py:906):wait_for(get_me(), 10)task_done()только после успешногоget();FloodWaitловить доExceptionи спатьmin(e.value+5, 900)download_new_files:await put()→put_nowait()(оживитьexcept QueueFull)background_task/worker_taskв lifespan — CRITICAL-лог + перезапуск (rate-limit 1/60с)queue.join()завершаетсяГде не наебаться
wait_for— вокруг RPC, не вокруг_sem.acquire(): очередь на гейте — легитимный backpressure, иначе ложные таймауты при штатной пачке фидов.async forне заворачивается вwait_forнапрямую — только через промежуточную корутину.CancelledErrorне глотать (except Exceptionеё и так не ловит в 3.11 — не «улучшать» доBaseException).DoD
Ни один путь кода не ждёт Telegram без таймаута; воркер не умирает молча; pytest зелёный (174 baseline + новые).
Зависимости: нет. Деплоится первой.