Все темы К задачам
Тема 04
Управление контекстом
Разберись в теме, затем проверь понимание на задачах.
0/3 решено0%
О чём этот блок
Любой сетевой вызов, обработчик HTTP-запроса или фоновая задача должны уметь
остановиться: по таймауту, по сигналу остановки сервиса или потому что результат больше
не нужен. В Go для этого есть context.Context, и блок учит протаскивать отмену через все
уровни вызовов и останавливать работу так, чтобы не осталось ни одной зависшей горутины.
Если вы прошли блок 1, механика уже знакома. ctx.Done() — это тот же закрытый канал,
который видят все получатели сразу, а контексты связаны в дерево: отмена родителя
отменяет всех потомков.
Что понадобится
context.WithTimeoutповерх входящего контекста и обязательныйdefer cancel().- Один контекст на набор фоновых задач и ожидание их завершения после отмены.
- «Первый успешный ответ»: запрос к нескольким репликам, первый успех, отмена остальных.
- Понимание того, что отмена кооперативная: функция останавливается, только если сама
проверяет
ctx.Done(). - HTTP-запрос с контекстом и закрытие
resp.Body.
Задачи
- 13 · HTTP-запрос с жёстким таймаутом — таймаут 200 мс
поверх входного
ctx, запрос черезhttp.NewRequestWithContext. - 14 · Древовидная отмена (Graceful Shutdown) — один
контекст на несколько фоновых задач, каждая слушает
ctx.Done(), все завершаются без зависаний. - 15 · First Successful (быстрый ответ) — параллельные запросы к репликам, первый успех отменяет остальные. Отмена не прерывает функцию силой: проигравшие должны остановиться сами.
Что прочитать
- context — дерево отмены,
Done(), таймауты, обязательныйcancel, разбор HTTP-запроса перед задачей 13. - Утечки горутин и гонки — как проверить тестом, что после отмены не осталось горутин.
// Идиома блока: жёсткий таймаут поверх внешнего контекста.
ctx, cancel := context.WithTimeout(parent, 200*time.Millisecond)
defer cancel() // освобождает таймер, даже если успели вовремя