Go Golang

24 jan, 2023

Onde e qual Context utilizar

Publicidade

O package Context do Go é algo que vemos sendo cada vez mais utilizados por grandes packages. No entanto, não é nada estranho ver pessoas sem saber qual context utilizar dentre os diferentes tipos disponíveis.

Nesse post, vou falar sobre os diferentes tipos de context que temos, como fazemos para obtê-los e onde normalmente são utilizados.

Se você nunca viu esse package, aconselho assistir o vídeo Como funciona e para que serve o package Context (Golang) que temos no nosso canal do YouTube.

Bora começar?

Background context

A função abaixo retorna um context vazio.

Esse tipo de context não pode ser cancelado, ter valores ou deadline. No entanto ele pode ser passado para outras funções onde pode ser extendido para adicionar a habilidade de cancelamento, deadlines e valores.

Contexts vazios normalmente são utilizados na primeira camada da hierarquia de funções que utilizam context ou em testes.

TODO context

Embora essa função retorne EXATAMENTE o mesmo tipo de context que a função anterior, o TODO é utilizado quando não for claro qual tipo de context utilizar ou a utilização do context ainda não estiver disponível.

Um exemplo disso seria um package que tem uma API pública onde em futuras releases aceitará context, mas que ainda não faz nada com ele. Assim, para não causar incompatibilidade futura com a API pública, suas primeiras versões recebem um context do tipo TODO.

Context WithCancel

Essa função retorna uma cópia do context que foi passado para ela com um novo channel no atributo Done, para controlar o cancelamento do context atual ou do seu context pai.

Além do context, essa função também retorna uma função de cancelamento. Essa função pode ser executada a qualquer momento, cancelando assim a execução da função que recebeu esse novo context.

Quando executada, o context irá fechar o channel que foi criado no atributo Done e liberará todo recurso associado a execução.

Um exemplo de utilização, seria para lidar com grandes processamentos, onde o cliente precisa ficar conectado ao servidor. Caso essa conexão caia, podemos chamar a função de cancelamento para finalizar a execução.

Context WithDeadline

Similar ao context que vimos anteriormente, nesse caso também teremos o retorno de um novo context, tendo a base passada como context pai, e uma função para cancelamento.

A diferença aqui é que, mesmo que a função de cancelamento não seja chamada, caso a execução da função demore mais do que d(segundo parâmetro da função), o channel será fechado por ter excedido o tempo limite de execução.

Um bom exemplo de utilização desse tipo de context, é para quando precisamos executar requests a APIs externas ao nosso software.

No canal do YouTube, mostramos um exemplo no vídeo Utilizando Context para controlar requests em Golang.

Nessa chamada, um novo context será retornado contendo a chave e valor informados. Assim como nos anteriores, a “base” passada ficará como context pai do que foi retornado.

Como nós NUNCA devemos modificar uma request HTTP, esse tipo de context é normalmente utilizado para passar dados extras de request para outras funções, como por exemplo o id do usuário que está autenticado.

Dois pequenos avisos:

  1. Embora tanto key quanto value sejam do tipo any, existe uma validação interna nessa função que verifica se a key é do tipo comparable, ou seja, ela precisa ser de um tipo que podemos utilizar == ou ≠.
  2. NUNCA utilize esse tipo de context para passar parâmetros opcionais para uma função. Isso não sou eu falando, mas sim o TIME de desenvolvimento do Go.

Espero que esse post ajude você na hora de escolher qual tipo de context utilizar.

Até a próxima!