Алерт GlitchTip переживает недоступность Telegram: отправка уходит в фон, 502 остаётся #3485

Merged
lekss361 merged 1 commit from feat/3471-glitchtip-alert-queue into main 2026-09-12 11:22:46 +00:00
Owner

Пункт из #3471, связано с #3157.

Что было

При отказе Telegram приёмник вебхуков отвечал 502, и на этом всё заканчивалось: GlitchTip вебхуки не ретраит, он безусловно помечает уведомление отправленным. Алерт исчезал бесследно.

Масштаб честный: ровно одно такое событие за всё время эксплуатации, 28.08. Но сеть до Telegram с этого хоста теряет примерно каждый четвёртый короткий запрос, так что случай повторится.

Что сделано

502 сохранён намеренно — он задуман в #3456 и остаётся честным сигналом отправителю. Изменилось другое: перед ответом отправка ставится в фон и повторяется там.

Неочевидная деталь, которую стоит знать. Первая реализация использовала зависимость BackgroundTasks из FastAPI, и задача не выполнялась вовсе: фоновые задачи привязываются к ответу, который вернул сам обработчик, а raise HTTPException строит отдельный ответ в мидлваре исключений. Поймано тестом. Поэтому здесь JSONResponse со статусом 502 возвращается явно, с BackgroundTask на нём.

Celery не использован, потому что его нет. В Trade-In нет ни celery_app, ни зависимости в pyproject: очередь живёт в бэкенде Site Finder. Поэтому потолок повторов маленький и осознанный: три попытки с паузой в 30 секунд поверх штатной политики клиента, на исчерпании — запись уровня error с текстом алерта, а не молчание.

Ограничение записано прямым текстом: фоновая задача не переживает рестарт процесса. Для события, случившегося один раз за всё время, это приемлемо; персистентная очередь потребовала бы воркера, то есть инфраструктуры, и это отдельный разговор.

Идемпотентность дешёвая: повторно отправляется уже собранный текст, без пересборки. Полной её быть не может, sendMessage сам по себе не идемпотентен, поэтому потолок мал.

Новых переменных окружения нет.

Тесты

23 проходят. Покрыто: отказ синхронной попытки ставит фон и всё равно отдаёт 502; успешная отправка фон не ставит; повтор на потолке сдаётся с записью уровня error.

Пункт из #3471, связано с #3157. ## Что было При отказе Telegram приёмник вебхуков отвечал 502, и на этом всё заканчивалось: GlitchTip вебхуки не ретраит, он безусловно помечает уведомление отправленным. Алерт исчезал бесследно. Масштаб честный: ровно одно такое событие за всё время эксплуатации, 28.08. Но сеть до Telegram с этого хоста теряет примерно каждый четвёртый короткий запрос, так что случай повторится. ## Что сделано 502 сохранён намеренно — он задуман в #3456 и остаётся честным сигналом отправителю. Изменилось другое: перед ответом отправка ставится в фон и повторяется там. **Неочевидная деталь, которую стоит знать.** Первая реализация использовала зависимость `BackgroundTasks` из FastAPI, и задача не выполнялась вовсе: фоновые задачи привязываются к ответу, который вернул сам обработчик, а `raise HTTPException` строит отдельный ответ в мидлваре исключений. Поймано тестом. Поэтому здесь `JSONResponse` со статусом 502 возвращается явно, с `BackgroundTask` на нём. **Celery не использован, потому что его нет.** В Trade-In нет ни `celery_app`, ни зависимости в pyproject: очередь живёт в бэкенде Site Finder. Поэтому потолок повторов маленький и осознанный: три попытки с паузой в 30 секунд поверх штатной политики клиента, на исчерпании — запись уровня error с текстом алерта, а не молчание. **Ограничение записано прямым текстом:** фоновая задача не переживает рестарт процесса. Для события, случившегося один раз за всё время, это приемлемо; персистентная очередь потребовала бы воркера, то есть инфраструктуры, и это отдельный разговор. Идемпотентность дешёвая: повторно отправляется уже собранный текст, без пересборки. Полной её быть не может, `sendMessage` сам по себе не идемпотентен, поэтому потолок мал. Новых переменных окружения нет. ## Тесты 23 проходят. Покрыто: отказ синхронной попытки ставит фон и всё равно отдаёт 502; успешная отправка фон не ставит; повтор на потолке сдаётся с записью уровня error.
lekss361 added 1 commit 2026-09-12 11:12:09 +00:00
feat(glitchtip): фоновая ретрай-доставка алерта в Telegram при отказе синхронной попытки
All checks were successful
CI Trade-In / changes (pull_request) Successful in 15s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / changes (pull_request) Successful in 27s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 8m54s
9eb42607b9
GlitchTip не ретраит вебхуки (#3157) — is_sent проставляется безусловно сразу
после HTTP-ответа приёмника. При отказе Telegram синхронная попытка отвечала
502 и текст алерта пропадал безвозвратно (TRADE-IN-3F7, 28.08.2026; сеть до
Telegram с хоста теряет ~каждый четвёртый запрос — замер 12.09).

502 при отказе Telegram ОСТАВЛЕН как есть — он задуман осознанно (#3456) как
честный сигнал отправителю. Меняется судьба самого текста: перед возвратом 502
доставка ставится в фон через starlette.background.BackgroundTask на самом
JSONResponse (app.tasks.glitchtip_alert_retry.retry_forward_alert), а не через
FastAPI BackgroundTasks-зависимость — та привязывает задачи только к ответу,
который вернул сам хендлер, а `raise HTTPException` строит отдельный ответ в
exception-мидлваре, и такая задача не выполнилась бы вовсе (воспроизведено
тестом при первой попытке реализации).

Celery в проекте нет: ни app/celery_app.py, ни зависимости celery в
backend/pyproject.toml не существует — бутстрап полноценной очереди с воркером
вне границ этой задачи (новый контейнер/брокер). Фон использует штатную
"воркерную" ретрай-политику TelegramClient.send_message (5 попыток, backoff до
30s) плюс свой внешний потолок в 3 попытки, чтобы недоставляемый алерт не
крутился вечно — при исчерпании сдаётся с ERROR-логом текста. Переиспользует
существующее форматирование (_build_message) и общий клиент приложения, без
дублирования и новых переменных окружения.

Refs #3471, #3157
lekss361 merged commit 382f266801 into main 2026-09-12 11:22:46 +00:00
lekss361 deleted branch feat/3471-glitchtip-alert-queue 2026-09-12 11:22:46 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3485
No description provided.