Junior
O que é o contexto em Go?
sobes.tech IA
Resposta da IA
O contexto (context.Context) em Go é um objeto que transporta um prazo limite, um sinal de cancelamento e dados específicos da solicitação. É usado para gerenciar o ciclo de vida das goroutines e para transmitir informações entre elas durante a execução de uma solicitação/operação.
Características principais:
- Seguro para concorrência: Pode ser transferido com segurança entre goroutines.
- Imutável: Uma vez criado, um
Contextnão pode ser alterado. Os contextos derivados são criados a partir do pai. - Hierárquico: Os contextos formam uma árvore com raiz (
context.Background()oucontext.TODO()). O cancelamento do contexto pai leva ao cancelamento de todos os seus filhos.
Funções principais do pacote context:
context.Background(): Contexto vazio, geralmente usado na função main, em solicitações de alto nível ou em testes. Nunca é cancelado.context.TODO(): Também um contexto vazio. Usado como marcador de posição quando não se sabe qual contexto usar, ou se a funcionalidade do contexto ainda não foi implementada.context.WithCancel(parent Context): Retorna um novo contexto filho e uma função de cancelamento. Chamar essa função cancela este contexto e todos os seus contextos filhos.context.WithDeadline(parent Context, deadline time.Time): Retorna um contexto filho que é automaticamente cancelado quando o tempo especificado chega. Também retorna uma função de cancelamento para cancelamento manual.context.WithTimeout(parent Context, timeout time.Duration): Igual aWithDeadline, mas especificando uma duração.context.WithValue(parent Context, key, val interface{}): Retorna um contexto filho com um valor associado a uma chave.
Aplicações:
- Cancelar operações: Por exemplo, um timeout em uma requisição HTTP ou a interrupção de uma operação prolongada.
- Transmissão de dados: Por exemplo, ID de requisição para registro, informações de autenticação.
Exemplo 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):
// Operação concluída com sucesso
resultChan <- "Operação concluída"
case <-ctx.Done():
// O contexto foi cancelado
err := ctx.Err() // Obtemos a causa do cancelamento
resultChan <- fmt.Sprintf("Operação cancelada: %v", err)
}
}
func main() {
// Cria um contexto com timeout de 2 segundos
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel() // Garantir chamada de cancel
resultChan := make(chan string, 1)
go longRunningOperation(ctx, resultChan)
// Espera pelo resultado ou cancelamento
select {
case res := <-resultChan:
fmt.Println(res)
case <-ctx.Done():
fmt.Printf("Context principal terminado: %v\n", ctx.Err())
}
// Espera um pouco para que a goroutine termine, se foi cancelada
time.Sleep(1 * time.Second)
}
Neste exemplo, longRunningOperation verifica se o contexto foi cancelado. Se o timeout do contexto principal (2 segundos) expirar antes que a operação termine (3 segundos), a goroutine recebe o sinal de cancelamento através de ctx.Done() e termina.