Долг: постфактум-ревью медиа-самолечения (3c9ce72, влито в main без ревью)
#43
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?
Контекст
Инцидент: перестали грузиться картинки в ленте (серые заглушки). Первопричина — Kurigram сериализует скачивания через один слот (
MAX_CONCURRENT_TRANSMISSIONS=1), а зомби-соединение с медиа-DC (upload.GetFileуходил в вечный таймаут) держало этот слот, блокируя все загрузки. Watchdog не видел проблему, т.к. пробит только главный DC (get_me). Лечилось руками черезdocker restart.Фикс
3c9ce72(fix(media): self-heal zombie media-DC connection so images keep loading) сделан и влит напрямую вmainбез обычного PR-ревью под давлением прод-аварии. Этот issue — долг на ретроспективное ревью.Изменённые файлы:
telegram_client.py,config.py,api_server.py,dockercompose.yml,tests/mock_config.py,tests/test_media_selfheal.py.Что сделано
telegram_client.py): N подряд идущих таймаутов скачивания (MEDIA_TIMEOUT_RESTART_THRESHOLD, дефолт 5) →_restart_client()(переиспользован путь watchdog). Успех сбрасывает streak.max_concurrent_transmissions(config.py+ Client, дефолт 3) — чтобы одна зависшая загрузка не была мгновенным полным отказом.api_server.py) — стабильно падающий файл не долбится каждые 60с: пропуск вdownload_new_files, быстрый 503Retry-Afterвget_media,record/clearв_download_deduped._runnerиbackground_download_worker(FloodWait бэкофф не взводит).На что смотреть при ревью (потенциальные риски)
max_concurrent_transmissions=3: обоснование значения; больше параллельных соединений к медиа-DC — нет ли риска FLOOD_WAIT; согласование сHTTP_DOWNLOAD_SEMAPHORE(3)иBACKGROUND_DOWNLOAD_SEMAPHORE(2).asyncio.wait_forпри таймауте действительно отменяетdownload_mediaи освобождаетget_file_semaphoreKurigram. Тестом это НЕ покрыто (есть только юниты на streak/бэкофф) — стоит проверить на реальном зависании._download_failuresрастёт без вытеснения — теоретически неограниченно (ограничено числом когда-либо падавших файлов; удалённые файлы вычищаются из БД). Нужна ли эвикция по времени/размеру?(str(channel), int(post_id), file_unique_id)во всех точках (get_media / _runner / worker / download_new_files) — перепроверить, чтоstr(channel)==str(channel_id)иpost_idвезде int.tests/test_media_selfheal.py(5 тестов) — нет интеграционного сценария «джем → авто-восстановление».Примечания
Диагностика подтверждена на живом контейнере: после рестарта тот самый «зависший» файл скачался за <2с. Прод расклинен ручным рестартом на момент фикса.