Введение
Этот лабораторный практикум旨在演示context.Context
在Golang中用于控制取消操作的用法。Context
跨API边界和goroutine携带截止日期、取消信号及其他请求范围的值。
This tutorial is from open-source community. Access the source code
💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал
Этот лабораторный практикум旨在演示context.Context
在Golang中用于控制取消操作的用法。Context
跨API边界和goroutine携带截止日期、取消信号及其他请求范围的值。
Функция hello
имитирует некоторую работу, выполняемую сервером, ожидая несколько секунд перед отправкой ответа клиенту. Во время работы следите за каналом Done()
контекста на сигнал о том, что мы должны отменить работу и вернуться как можно скорее.
## Запустите сервер в фоновом режиме.
$ go run context-in-http-servers.go &
## Имитируйте запрос клиента к `/hello`, нажав
## Ctrl+C вскоре после запуска для сигнализации
## отмены.
$ curl localhost:8090/hello
server: hello handler started
^C
server: context canceled
server: hello handler ended
Ниже представлен полный код:
// В предыдущем примере мы рассматривали настройку простого
// [HTTP-сервера](http-servers). HTTP-сервера полезны для
// демонстрации использования `context.Context` для
// управления отменой. `Context` переносит даты окончания,
// сигналы отмены и другие значения, относящиеся к запросу,
// через границы API и goroutine.
package main
import (
"fmt"
"net/http"
"time"
)
func hello(w http.ResponseWriter, req *http.Request) {
// `context.Context` создается для каждого запроса
// механизмом `net/http` и доступен с помощью
// метода `Context()`.
ctx := req.Context()
fmt.Println("server: hello handler started")
defer fmt.Println("server: hello handler ended")
// Подождите несколько секунд перед отправкой ответа
// клиенту. Это может имитировать некоторую работу,
// выполняемую сервером. Во время работы следите за
// каналом `Done()` контекста на сигнал о том, что мы
// должны отменить работу и вернуться как можно скорее.
select {
case <-time.After(10 * time.Second):
fmt.Fprintf(w, "hello\n")
case <-ctx.Done():
// Метод `Err()` контекста возвращает ошибку,
// которая объясняет, почему канал `Done()` был
// закрыт.
err := ctx.Err()
fmt.Println("server:", err)
internalError := http.StatusInternalServerError
http.Error(w, err.Error(), internalError)
}
}
func main() {
// Как и раньше, мы регистрируем наш обработчик на
// маршруте "/hello" и начинаем обслуживание.
http.HandleFunc("/hello", hello)
http.ListenAndServe(":8090", nil)
}
В этом лабораторном практикуме мы узнали, как использовать context.Context
для управления отменой в Golang. Создав Context
с таймаутом и передав его в функцию, мы можем убедиться, что функция вернется как можно скорее, если превышен таймаут.