Junior
¿Qué es el contexto en Go?
sobes.tech AI
Respuesta de la IA
El contexto (context.Context) en Go es un objeto que lleva un plazo límite, una señal de cancelación y datos específicos de la solicitud. Se usa para gestionar el ciclo de vida de las goroutines y para transmitir información entre ellas durante la ejecución de una solicitud/operación.
Características principales:
- Seguro para concurrencia: Puede transferirse de forma segura entre goroutines.
- Inmutable: Una vez creado, un
Contextno puede cambiarse. Los contextos derivados se crean a partir del padre. - Jerárquico: Los contextos forman un árbol con raíz (
context.Background()ocontext.TODO()). La cancelación del contexto padre lleva a la cancelación de todos los hijos.
Funciones principales del paquete context:
context.Background(): Contexto vacío, generalmente usado en la función main, en solicitudes de alto nivel o en pruebas. Nunca se cancela.context.TODO(): También un contexto vacío. Se usa como marcador de posición cuando no se sabe qué contexto usar, o si la funcionalidad del contexto aún no está implementada.context.WithCancel(parent Context): Devuelve un nuevo contexto hijo y una función de cancelación. Llamar a la función de cancelación cancela este contexto y todos sus contextos hijos.context.WithDeadline(parent Context, deadline time.Time): Devuelve un contexto hijo que se cancela automáticamente cuando llega la hora especificada. También devuelve una función de cancelación para cancelación manual.context.WithTimeout(parent Context, timeout time.Duration): Igual queWithDeadline, pero especificando una duración.context.WithValue(parent Context, key, val interface{}): Devuelve un contexto hijo con un valor asociado a una clave.
Aplicaciones:
- Cancelar operaciones: Por ejemplo, un timeout en una solicitud HTTP o la interrupción de una operación prolongada.
- Transmisión de datos: Por ejemplo, ID de solicitud para registro, información de autenticación.
Ejemplo de uso de context.WithTimeout:
package main
import (
"context"
"fmt"
"time"
)
func longRunningOperation(ctx context.Context, resultChan chan string) {
select {
case <-time.After(3 * time.Second):
// Operación completada con éxito
resultChan <- "Operación completada"
case <-ctx.Done():
// El contexto fue cancelado
err := ctx.Err() // Obtenemos la causa de la cancelación
resultChan <- fmt.Sprintf("Operación cancelada: %v", err)
}
}
func main() {
// Crear un contexto con timeout de 2 segundos
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel() // Garantizar llamada a cancel
resultChan := make(chan string, 1)
go longRunningOperation(ctx, resultChan)
// Esperar resultado o cancelación
select {
case res := <-resultChan:
fmt.Println(res)
case <-ctx.Done():
fmt.Printf("Context principal terminado: %v\n", ctx.Err())
}
// Esperar un poco para que la goroutine termine si fue cancelada
time.Sleep(1 * time.Second)
}
En este ejemplo, longRunningOperation verifica si el contexto fue cancelado. Si el timeout del contexto principal (2 segundos) expira antes de que la operación termine (3 segundos), la goroutine recibe la señal de cancelación a través de ctx.Done() y termina.