snow top mountain under clear sky

Como implementar uma função utilizando context

Nesse post vamos implementar uma função que utiliza context. No exemplo de chamada, vou utilizar o context WithTimeout. Dessa forma, conseguiremos fazer a função ser cancelada automaticamente, caso o tempo de execução dela ultrapasse o tempo estipulado no context.

Vamos iniciar criando uma função com o nome doSomeHeavyWork.

func doSomeHeavyWork(ctx context.Context, msg string) {
}

Para simular um processamento longo, vamos adicionar uma goroutine com um sleep de 2 segundos. Essa goroutine irá receber um channel do tipo bool. Ele irá sinalizar que a goroutine foi finalizada.

func doSomeHeavyWork(ctx context.Context, msg string) {
	c := make(chan bool)

	go func(c chan bool) {
		time.Sleep(2 * time.Second)
		c <- true
	}(c)
}

Na struct context.Context, temos um método chamado Done(). Esse método retorna um channel. Quando o context for finalizado, esse channel será fechado. Isso ocorrerá quando:

  • WithCancel – quando a função cancel for executada;
  • WithDeadline – quando a deadline expirar;
  • WithTimeout – quando timeout for atingido.

Como temos um channel de controle para o sleep e outro do context, precisamos adicionar um select para capturar o channel que foi acionado primeiro.

func doSomeHeavyWork(ctx context.Context, msg string) {
	c := make(chan bool)

	go func(c chan bool) {
		time.Sleep(2 * time.Second)
		c <- true
	}(c)

	select {
	case <-ctx.Done():
		fmt.Println("context timeout!")
	case <-c:
		fmt.Println(msg)
	}
}

Para testar nossa função, vamos criar um context com timeout de 1 segundo.

func main() {
	ctx, _ := context.WithTimeout(context.Background(), time.Second*1)

	doSomeHeavyWork(ctx, "work completed!")
}

Ao executar o programa com um go run main.go, teremos o seguinte resultado:

$ context timeout!

Alterando o tempo do nosso timeout para 3 segundos e, executando novamente o programa, o resultado será a mensagem de work completed!.

Se você quiser saber um pouco mais sobre os tipos de context disponíveis e quando normalmente são utilizados, recomendo a leitura do nosso post “Onde e qual context utilizar”.

Espero ter ajudado e até uma próxima!


Se inscreva na nossa newsletter

* indicates required

Deixe uma resposta