Camada Zero · 11 · Context, Cancel & Timeouts

No Go você não mata uma goroutine de fora. Você avisa que ela deve parar, e ela escolhe sair. O context é o canal desse aviso: ele desce do request por toda a árvore de chamadas, e um cancelamento no topo derruba a subárvore inteira. Crie filhos aqui embaixo, cancele o pai, e veja a propagação.
1Goroutines ativas
0Canceladas (saíram limpo)
0Vazadas (leak)
A raiz é o context do request. Clique em "criar filhos" pra abrir goroutines filhas, depois "cancelar pai" e veja o que acontece em cada modo.
ativa (rodando, ouvindo Done()) cancelada (saiu limpo) vazada (continua rodando à toa)
Cancelamento no Go é cooperativo. O runtime não preempta nem mata a goroutine: ela precisa escutar ctx.Done() e retornar por conta própria. Se ela não escuta e fica bloqueada, vira leak. O context flui do topo (o request HTTP) pra baixo, sempre como primeiro argumento, e um cancel ou timeout lá em cima libera todo mundo.

WithCancel: aviso manual

ctx, cancel := context.WithCancel(parent)
defer cancel() // sempre libere o context

go worker(ctx)
// ... quando desistir:
cancel() // fecha ctx.Done() pra toda a subárvore

WithTimeout: aviso automático

ctx, cancel := context.WithTimeout(parent, 2*time.Second)
defer cancel()
// cancela sozinho após 2s. Limita request, query, RPC.

Como a goroutine ouve

func worker(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            return // avisado: sai limpo
        case job := <-jobs:
            handle(job)
        }
    }
}

🧠 Desafio — Context & Cancel

Brinca com criar filhos, cancelar e o timeout (nos dois modos) antes de responder. As duas últimas são de reflexão: escreve a sua e só então revela o modelo.