Вопрос проверяет понимание механизма отмены HTTP-запросов через контекст в Go, что важно для управления ресурсами и предотвращения утечек.
В Go контекст (context.Context) является стандартным механизмом для управления временем жизни операций, включая HTTP-запросы. Он позволяет отменить запрос, установить таймаут или дедлайн, а также передавать метаданные. Это критически важно для создания надёжных и масштабируемых приложений, где нужно избегать зависших соединений и утечек горутин.
Основная идея — создать контекст с возможностью отмены и передать его в запрос. Когда контекст отменяется (например, по таймауту или вручную), HTTP-клиент прерывает запрос и закрывает соединение. Это особенно полезно при работе с внешними API, где ответ может задерживаться.
package main
import (
"context"
"fmt"
"net/http"
"time"
)
func main() {
// Создаём контекст с таймаутом 2 секунды
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel() // обязательно вызываем cancel для освобождения ресурсов
req, err := http.NewRequestWithContext(ctx, "GET", "https://example.com", nil)
if err != nil {
panic(err)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
// Проверяем, была ли отмена по контексту
if ctx.Err() == context.DeadlineExceeded {
fmt.Println("Request timed out")
} else {
fmt.Println("Error:", err)
}
return
}
defer resp.Body.Close()
fmt.Println("Status:", resp.Status)
}context.WithCancel для ручной отмены или context.WithTimeout/context.WithDeadline для автоматической.cancel) через defer, чтобы избежать утечек ресурсов.http.NewRequestWithContext, а не в сам клиент.client.Do вернёт ошибку, связанную с контекстом.Передача контекста отмены в HTTP-запросы — это стандартная практика в Go для управления временем выполнения и предотвращения зависших соединений. Она обязательна в production-приложениях, особенно при работе с внешними сервисами или в микросервисной архитектуре.