Noções básicas de context
10 exemplos para você começar com o Pacote context - 7 básicos e 3 intermediários.
Busque em todas as páginas da documentação
10 exemplos para você começar com o Pacote context - 7 básicos e 3 intermediários.
mkdir ctxdemo && cd ctxdemo && go mod init example.com/ctxdemo.main.go (ou arquivos separados em um pacote) e execute com go run ..Contextos raiz iniciam cadeias que não têm cancelamento pai.
package main
import (
"context"
"fmt"
)
func main() {
fmt.Println(context.Background().Err() == nil)
fmt.Println(context.TODO().Err() == nil)
}context.Background() é o context vazio de nível superior para main, servidores e testes.context.TODO() é um placeholder durante refatorações quando o pai ainda não está conectado.Relacionado: context.Context: Cancelamento como uma API de Primeira Classe - por que o context existe
O cancelamento manual interrompe o trabalho descendente.
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
<-ctx.Done()
fmt.Println("parou:", ctx.Err())
}()
time.Sleep(50 * time.Millisecond)
cancel()
time.Sleep(20 * time.Millisecond)
}WithCancel retorna um context filho e uma função cancel.defer cancel() para liberar recursos, mesmo que você cancele antecipadamente.ctx.Err() retorna context.Canceled após o cancelamento manual.Relacionado: Propagação de Cancelamento em Manipuladores HTTP - tempos de vida de requisição reais
Um deadline relativo cancela automaticamente.
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
select {
case <-time.After(250 * time.Millisecond):
fmt.Println("trabalho concluído")
case <-ctx.Done():
fmt.Println("tempo esgotado:", ctx.Err())
}
}WithTimeout(parent, d) é um atalho para WithDeadline(parent, time.Now().Add(d)).Done() fecha e Err() é context.DeadlineExceeded.Relacionado: Deadlines e Timeouts Entre Limites de Serviço - orçamentos de serviço
Tempos absolutos de relógio de parede são adequados para expiração fornecida por upstream.
package main
import (
"context"
"fmt"
"time"
)
func main() {
deadline := time.Now().Add(80 * time.Millisecond)
ctx, cancel := context.WithDeadline(context.Background(), deadline)
defer cancel()
if d, ok := ctx.Deadline(); ok {
fmt.Println("deadline:", d.Format(time.RFC3339))
}
<-ctx.Done()
fmt.Println(ctx.Err())
}Deadline() reporta o corte e se um deadline está definido.WithTimeout quando você pensa em durações; use WithDeadline ao sincronizar com um timestamp externo.Relacionado: Deadlines e Timeouts Entre Limites de Serviço - propagando expiração
Trabalho longo deve verificar o cancelamento entre iterações.
package main
import (
"context"
"fmt"
"time"
)
func work(ctx context.Context) error {
for i := 0; i < 10; i++ {
select {
case <-ctx.Done():
return ctx.Err()
default:
time.Sleep(30 * time.Millisecond)
fmt.Println("tick", i)
}
}
return nil
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
fmt.Println(work(ctx))
}select com default evita bloqueio quando o ctx ainda está ativo.ctx.Err() para que os chamadores distingam cancelamento de outras falhas.ctx em vez de polling feito manualmente quando disponível.Relacionado: Testando Código Que Aceita context.Context - afirmando caminhos de cancelamento
A forma padrão da função propaga o ciclo de vida para baixo na pilha.
package main
import (
"context"
"fmt"
)
func fetch(ctx context.Context, id int) (string, error) {
if err := ctx.Err(); err != nil {
return "", err
}
return fmt.Sprintf("user-%d", id), nil
}
func handler(ctx context.Context) error {
name, err := fetch(ctx, 42)
if err != nil {
return err
}
fmt.Println(name)
return nil
}
func main() {
_ = handler(context.Background())
}ctx e coloque-o primeiro - revisores e linters esperam isso.ctx.Err() antes de trabalho caro quando as chamadas são profundas.ctx para baixo; não crie um novo Background() no meio da requisição.Relacionado: Melhores Práticas do Pacote context - regras de nomenclatura da equipe
Chaves tipadas carregam dados de corte transversal com moderação.
package main
import (
"context"
"fmt"
)
type ctxKey string
const requestIDKey ctxKey = "requestID"
func withRequestID(ctx context.Context, id string) context.Context {
return context.WithValue(ctx, requestIDKey, id)
}
func requestID(ctx context.Context) string {
v, _ := ctx.Value(requestIDKey).(string)
return v
}
func main() {
ctx := withRequestID(context.Background(), "req-abc")
fmt.Println(requestID(ctx))
}Relacionado: Valores de Contexto: Quando e Quando Não - disciplina de valores
O cancelamento flui apenas do pai para o filho.
package main
import (
"context"
"fmt"
)
func main() {
parent, parentCancel := context.WithCancel(context.Background())
defer parentCancel()
child, childCancel := context.WithCancel(parent)
defer childCancel()
childCancel()
fmt.Println("erro pai:", parent.Err())
fmt.Println("erro filho:", child.Err())
}childCancel() define child.Err() como context.Canceled.parentCancel() seja executado.Relacionado: Antipadrões de Mau Uso de Contexto - erros de ciclo de vida
Cada camada deve subtrair a sobrecarga do orçamento restante.
package main
import (
"context"
"fmt"
"time"
)
func callDownstream(parent context.Context) error {
ctx, cancel := context.WithTimeout(parent, 50*time.Millisecond)
defer cancel()
select {
case <-time.After(200 * time.Millisecond):
return nil
case <-ctx.Done():
return ctx.Err()
}
}
func main() {
parent, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
fmt.Println(callDownstream(parent))
}DeadlineExceeded na camada que definiu o timeout mais curto para facilitar a depuração.Relacionado: Deadlines e Timeouts Entre Limites de Serviço - orçamentos de salto
Anexe uma razão ao cancelamento para erros mais claros.
package main
import (
"context"
"errors"
"fmt"
)
func main() {
ctx, cancel := context.WithCancelCause(context.Background())
defer cancel(nil)
cause := errors.New("falha na validação upstream")
cancel(cause)
fmt.Println(context.Cause(ctx))
}WithCancelCause emparelha com context.Cause(ctx) para observabilidade.ctx.Err() nas fronteiras da API, a menos que os chamadores precisem da causa.Relacionado: Testando Código Que Aceita context.Context - afirmando causas de cancelamento
Versões da Stack: Esta página foi escrita para Go 1.26.x (padrão GC Green Tea, go fix modernizers - verifique o patch na compilação), chi (última versão - verifique na compilação), gin (última versão - verifique na compilação), echo (última versão - verifique na compilação), google.golang.org/grpc (última versão - verifique na compilação), sigs.k8s.io/controller-runtime (última versão - verifique na compilação), kubebuilder (última versão - verifique na compilação), tinygo (última versão - verifique os alvos de placa na compilação), wazero (última versão - verifique na compilação) e golangci-lint (última versão - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 18 de jul. de 2026