O que é e como utilizar o package context

No desenvolvimento de aplicações em Go, é comum enfrentar situações em que precisamos gerenciar o tempo de vida de processos, propagar cancelamentos de tarefas ou passar dados entre goroutines.

Para resolver esses problemas, a própria linguagem fornece um package chamado context.

Nesse post, vamos explorar juntos o que é o package context, para que ele serve, onde normalmente é utilizado e como implementá-lo em suas aplicações Go.

Hello Context

O package context foi introduzido na versão 1.7 do Go e é utilizado para gerenciar deadlines, cancelamentos e outros valores através de limites de API e entre goroutines. Sua principal função é gerenciar o tempo de vida de uma operação, especialmente em servidores e aplicativos web, onde operações longas podem ser canceladas se excederem um determinado tempo ou se a solicitação do cliente for cancelada.

Utilização

  • Propagação de cancelamento: Permite que uma operação em execução possa ser cancelada. Um exemplo seria cancelar a execução da goroutine B se a execução da goroutine A falhar.
  • Deadlines e timeouts: Define um tempo máximo de execução para uma operação. Normalmente utilizado para controlar requests à APIs ou conexão com bancos de dados, queues e etc.
  • Transporte de dados entre processos: Facilita o compartilhamento de dados específicos de uma solicitação entre funções, como por exemplo a opção Request.Context() do package net/http.

Context na prática

Para entender melhor sua utilização, no exemplo abaixo, utilizamos o context para controlar o timeout de uma request, onde, caso a operação não seja concluída em 2 segundos, a requisição será cancelada.

package main

import (
    "context"
    "fmt"
    "net/http"
    "time"
)

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
    // Cria um context com timeout de 2 segundos
    ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
    defer cancel() // Assegura que o cancelamento seja chamado

		// ... código para executar algo

    select {
    case <-ctx.Done():
        // Timeout ou cancelamento
        http.Error(w, "Request cancelada ou timeout", http.StatusRequestTimeout)
    case result := <-resultChan:
		    // Resultado com sucesso!
        fmt.Fprintln(w, result)
    }
}

Outro exemplo seria fornecer o context como um parâmetro de uma função, para que cada chamada à ela defina suas condições de cancelamento/timeout.

package main

import (
    "context"
    "fmt"
    "time"
)

// Função que realiza uma tarefa longa
func longRunningTask(ctx context.Context) (string, error) {
    resultChan := make(chan string, 1)
    
    go func() {
        // Simula uma operação longa
        time.Sleep(5 * time.Second)
        resultChan <- "Tarefa completa"
    }()

    select {
    case <-ctx.Done():
        // Operação foi cancelada ou houve timeout
        return "", ctx.Err()
    case result := <-resultChan:
        return result, nil
    }
}

Boas práticas

  1. Cancele contexts explicitamente: Sempre chame a função cancel para liberar recursos.
  2. Evite o uso de context.Background e context.TODO: Utilize-os apenas em testes ou funções principais.
  3. Passe context como primeiro parâmetro: Siga a convenção de passar o contexto como o primeiro argumento em funções.
  4. Evite armazenar context em structs: Contextos devem ser passados explicitamente para funções e não armazenados em structs para evitar vazamento de memória.

Conclusão

O package context é uma ferramenta poderosa no arsenal de um desenvolvedor Go, proporcionando controle eficiente sobre o tempo de vida de operações e facilitando o gerenciamento de cancelamentos e deadlines. Seguindo as boas práticas, você pode garantir que suas aplicações sejam mais robustas, responsivas e eficientes.

Se você quer saber mais sobre o package context, leia também:

Assine nossa newsletter e receba os conteúdos do blog toda semana diretamente na sua caixa de e-mail.

Até a próxima!


Faça parte da comunidade!

Receba os melhores conteúdos sobre Go, Kubernetes, arquitetura de software, Cloud e esteja sempre atualizado com as tendências e práticas do mercado.

Livros Recomendados

Abaixo listei alguns dos melhores livros que já li sobre GO.

Um comentário sobre “O que é e como utilizar o package context

Deixe uma resposta