Go by Example: Context

En el ejemplo anterior vimos cómo configurar un simple servidor HTTP. Los servidores HTTP son útiles para demostrar el uso de context.Context para controlar la cancelación. Un Context lleva plazos, señales de cancelación y otros valores específicos de la solicitud a través de límites de API y goroutines.

package main
import (
    "fmt"
    "net/http"
    "time"
)
func hello(w http.ResponseWriter, req *http.Request) {

Un context.Context se crea para cada solicitud por la maquinaria de net/http, y está disponible con el método Context().

    ctx := req.Context()
    fmt.Println("server: hello handler started")
    defer fmt.Println("server: hello handler ended")

Espera unos segundos antes de enviar una respuesta al cliente. Esto podría simular algún trabajo que el servidor está realizando. Mientras trabaja, mantén un ojo en el canal Done() del contexto para una señal de que deberíamos cancelar el trabajo y regresar lo antes posible.

    select {
    case <-time.After(10 * time.Second):
        fmt.Fprintf(w, "hello\n")
    case <-ctx.Done():

El método Err() del contexto devuelve un error que explica por qué se cerró el canal Done().

        err := ctx.Err()
        fmt.Println("server:", err)
        internalError := http.StatusInternalServerError
        http.Error(w, err.Error(), internalError)
    }
}
func main() {

Como antes, registramos nuestro manejador en la ruta “/hello” y comenzamos a servir.

    http.HandleFunc("/hello", hello)
    http.ListenAndServe(":8090", nil)
}

Ejecuta el servidor en segundo plano.

$ go run context-in-http-servers.go &

Simula una solicitud de cliente a /hello, presionando Ctrl+C poco después de comenzar para señalar la cancelación.

$ curl localhost:8090/hello
server: hello handler started
^C
server: context canceled
server: hello handler ended

Siguiente ejemplo: Spawning Processes.