Compreendendo contextos em Go

Compreendendo contextos em Go

O contexto é um dos recursos críticos em Go que permite a simultaneidade. Em Go, “contexto” refere-se a um pacote que fornece funcionalidade para valores com escopo de solicitação e sinais de cancelamento nos limites da API.

O pacote de contexto funciona simultaneamente com o modelo de concorrência do Go, baseado no conceito de goroutines. Goroutines são threads leves de execução que você pode criar e gerenciar com eficiência, facilitando a criação de programas simultâneos em Go.

O pacote de contexto

O pacote de contexto fornece funcionalidade para cancelar funções de execução longa ou cadeias de chamadas inteiras. O pacote também ajuda a armazenar valores com escopo de solicitação para acesso em qualquer lugar dentro da cadeia de chamadas. Esse recurso é útil ao trabalhar com APIs ou microsserviços, onde as solicitações podem abranger várias chamadas de função e você deseja cancelá-las ou anexar valores específicos a elas.

Veja como você pode importar o pacote de contexto em seus programas Go.

import "context"

As funções de contexto aceitam o tipo de estrutura Context do pacote de contexto. Convencionalmente, você deve usar ctx como o nome da variável de instância.

func operations(ctx context.Context) {
}

As funções podem retornar o tipo struct Context para outras funções e operações.

func operations(ctx context.Context) context.Context {
}

Você pode criar um novo contexto com a função TODO do pacote de contexto. A função TODO cria um novo contexto com o valor de context.Done() , um canal que será fechado no cancelamento do contexto. Você deve usá-lo como um espaço reservado quando precisar de um contexto, mas nenhum contexto pai for adequado.

import "context"

func main() {
    ctx: = context.TODO()
}

Como alternativa, a função Background cria um novo contexto sem valor e um canal Done vazio.

ctx: = context.Background()

Você deve usar a função Background como raiz de uma árvore de contexto.

Contexto com valores

O pacote de contexto fornece funcionalidade para propagar valores e sinais de cancelamento. Você pode usar os valores para obter informações de dados com escopo de solicitação para sinais de cancelamento e prazos.

O pacote de contexto também permite a criação de contexto filho herdado de contextos pai, permitindo a manipulação eficiente de valores e sinais de cancelamento em todo o programa, pois você pode passar o contexto por várias funções.

Aqui está um exemplo de passagem de contexto através de funções com o pacote context.

import (
    "context"
)

func valuableContext(ctx context.Context) context.Context {
    return context.WithValue(ctx, "pass-key", "hfouneqcelkwfu")
}


func receiveContextData(ctx context.Context) any {
    passKey: = ctx.Value("pass-key")
    return passKey
}

A função valueContext recebe uma instância de contexto e retorna uma instância de contexto para a função a seguir. A instância de contexto é um valor criado com o método WithValue . O método WithValue pega a instância de contexto da função e um par chave-valor.

Para recuperar os dados do contexto, você precisará criar um novo contexto com a função TODO ou Background e passar o contexto para a função (neste caso, valueContext) e receber o contexto com a função receiveContextData .

func main() {
    ctx: = context.Background()
    ctx = valuableContext(ctx)
    fmt.Println(receiveContextData(ctx))

}

A variável ctx é a instância de contexto da função Background. A função valueContext recebe a variável ctx e retorna o contexto com um valor que a função receiveContextData recebe e retorna o valor do par chave-valor.

contexto por resultado de código de valor

Limites de tempo e prazos de contexto

O pacote de contexto fornece funcionalidade para definir tempos limite e prazos nas operações. Definir tempos limite e prazos é útil para operações que precisam ser atualizadas.

Timeouts são a duração de tempo que uma operação leva. Você pode definir um tempo limite para uma operação de 4 segundos; depois disso, o contexto cancela a solicitação.

Por outro lado, um deadline define o ponto absoluto em que uma operação deve ser cancelada.

Você pode usar o método WithTimeout para definir um tempo limite de contexto. Veja como você pode definir um tempo limite de 2 segundos.

func main() {
    ctx, cancel: = context.WithTimeout(context.Background(), 2 * time.Second)
    defer cancel()

    // some operation
}

A função principal cria um contexto com um tempo limite de dois segundos. A função WithTimeout retorna uma função de cancelamento que você pode adiar para cancelamento na saída da função principal.

Você pode declarar prazos com o método WithDeadline . O método WithDeadline considera uma instância de contexto e um prazo final.

func doSomething(ctx context.Context) {
    deadlineTime: = time.Now().Add(1500 * time.Millisecond)
    ctx, ctxCancel: = context.WithDeadline(ctx, deadlineTime)
    defer ctxCancel()

    // some operation


    ctxCancel()
}

A função doSomething leva em um contexto, e a variável deadlineTime é o tempo antes do deadline do contexto . A variável ctx é o contexto com um deadline.

A variável ctxCancel cancela o contexto quando o contexto excede seu prazo.

Melhores práticas para usar contextos em Go

Evite usar contextos como variáveis ​​globais. O uso de contextos como variáveis ​​globais pode levar a comportamentos de código inesperados e erros difíceis de rastrear, e use o contexto com moderação para reduzir a complexidade do código.

Finalmente, use contextos como sinais, não como garantias. Cancelar um contexto não garante que todas as goroutines irão parar de rodar; é meramente um sinal, e goroutines são independentes de contextos.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *