- имя приведено к конвенции, которая сама называла его расхождением; ссылки поправлены в README, CLAUDE.md, конвенциях, docs/review.md и двух записях задач - в шапке docs/conventions/config.md заодно поправлен второй пункт перечня: проверки на старте у `[auth]` и `[telegram]` уже есть - архив openspec/changes/archive/ не тронут: это запись о прошлом
47 lines
3.7 KiB
Markdown
47 lines
3.7 KiB
Markdown
# 🧹 Задать таймауты обращениям к внешним сервисам
|
||
|
||
- **Тип:** chore
|
||
- **Категория:** Очередь — Молчащий внешний сервис держит шаг до истечения часового захвата — правится под свежими тестами конвейера.
|
||
- **Зачем:** Ни у Telegram, ни у Object Storage, ни у SpeechKit нет таймаута: молчащий собеседник держит шаг конвейера до истечения часового захвата.
|
||
|
||
Все обращения наружу идут с `context.Background()` либо через `http.Get` без
|
||
клиента со своим таймаутом. Отказ такого рода в
|
||
[architecture.md](../../docs/architecture.md) назван условием: собеседник,
|
||
который «отвечает медленно», сегодня останавливает воркер целиком, и заметить
|
||
это можно только по тому, что задачи перестали двигаться.
|
||
|
||
Сюда же контекст: воркеры получают `ctx` и отменяют его при остановке, но ни
|
||
один шаг конвейера внутрь его не передаёт — мягкая остановка ждёт таймаута
|
||
вместо того, чтобы прервать вызов.
|
||
|
||
## Затрагивает
|
||
|
||
- `internal/adapter/recognizer/yandex/s3.go` — заливка объекта;
|
||
- `internal/adapter/recognizer/yandex/speechkit.go` — запуск распознавания,
|
||
чтение потока, опрос операции;
|
||
- `internal/controller/tg/tg.go` — скачивание файла через `http.Get`;
|
||
- `internal/adapter/telegram/sender.go` — отправка сообщения;
|
||
- `internal/contract/contract.go` — интерфейсам нужен `context.Context` первым
|
||
аргументом;
|
||
- `internal/controller/worker/worker.go` и `internal/service/transcribe.go` —
|
||
протаскивание контекста в шаг;
|
||
- `config.example.toml` и `internal/config` — числа таймаутов;
|
||
- `docs/database.md`, таблица настроек с числовым значением.
|
||
|
||
## Критерии приёмки
|
||
|
||
- У каждого обращения наружу есть таймаут, и его значение задаётся конфигом.
|
||
Оракул — тест на подставном сервере, который не отвечает: вызов
|
||
возвращается с ошибкой за назначенное время, а не висит.
|
||
- Прерванная по таймауту задача достаётся повторно и доходит до текста. Оракул
|
||
— тест на повторный прогон шага после отказа по таймауту.
|
||
- Числа таймаутов записаны в `docs/database.md`. Оракул — `task gate`.
|
||
|
||
## Рамки
|
||
|
||
Повторов с нарастающей паузой не заводим — это отдельная работа; здесь только
|
||
таймаут. Прерывание шага отменённым контекстом сюда не входит: методы записи
|
||
хранилища контекста не принимают вовсе, и этим занимается следующая задача
|
||
`context-cancel-in-pipeline`. Контекст первым аргументом интерфейсов эта задача
|
||
всё же протаскивает — без него таймаут некуда передать.
|