Como utiliza o pattern Heartbeats em Golang

Rafael Chinaglia
TOTVS Developers
Published in
3 min readJun 16, 2023

Artigo de Airton Lira para o iMasters

Durante minhas aventuras de equilibro entre data & software engineer, sempre pego algo um pouco diferente de GoLang para estudar o funcionamento e aplicar coisas mais complexas do alguns cursos e artigos tradicionais que encontro por ai. Nesse breve artigo vou relatar e demonstrar como implementei através Go Routines, utilizando Ticker para simular o batimento (i’m alive) da aplicação, canais etc..

Não é novidade para muitos que é de suma importancia garantir que quem chama determinada função saiba se a função esta demorando, processando, esta travada, e dito isso surgiram varias outras terminologias como Trace, Metrics, conectividade etc.. que foram introduzidas em aplicações de monitoria que usam na maioria dos dos casos agents instalados nos servidores da aplicação que coletam métricas e enviam para interface no qual você saber todo (ou quase) estado da sua aplicação, entre essas ferramentas temos DataDog, NewRelic, Slack, Grafana, Jager etc..

Tá, mas o que teremos aqui?

Como havia com objetivo de estudos e pensando em criar algo rapido e simples que abordase alguns conceitos de golang, criei uma aplicação relativamente simples no qual faz o papel do pattern heartbeats, ou seja, quem estiver me chamando recebe o resultado e ao mesmo tempo se ainda estou ativo ou não, em um cenário mais avançado isso pode ser interessante para customizar o que de fato é uma aplicativa conceitualmente a nivel de particularidade de negocio, visto que uma simples implementação de um prometheus resolve esse caso (aplicação esta ativa? CPU, Memoria), mas não com feedback simultaneo e customizável.

Hora do código!

A íivel de estrutura criei apenas 3 arquivos dentro do meu package com go mod:

  • dicionário.go: Vai conter um dicionario de nomes para a função fazer a busca.
  • task.go: É tarefa que contem a função de varrer os nomes do dicionário e ao mesmo tempo informar se ela esta ativa ou não via channel + beat do time.Ticker
  • task_test.go: Realiza um teste unitário da função presente no task.go para vermos tanto a resposta dos dados do dicionario como também o feedback de se a aplicação ainda esta Up!

Dicionário.go

Esta parte código em Go está definindo uma variável chamada “dicionario” que é um mapa (map) que associa caracteres do tipo rune a strings.

Cada entrada do mapa é uma chave (rune) e um valor (string). No exemplo acima, as chaves são letras minúsculas do alfabeto e os valores são nomes associados a cada letra. Por exemplo, a letra ‘a’ está associada ao nome “airton”, a letra ‘b’ está associada ao nome “bruno”, e assim por diante:

Task.go

Explico melhor abaixo após o código completo cada parte do código:

package heartbeat

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

func ProcessingTask(
ctx context.Context, letras chan rune, interval time.Duration,
) (<-chan struct{}, <-chan string) {

heartbeats := make(chan struct{}, 1)
names := make(chan string)

go func() {
defer close(heartbeats)
defer close(names)

beat := time.NewTicker(interval)
defer beat.Stop()

for letra := range letras {
select {
case <-ctx.Done():
return
case <-beat.C:
select {
case heartbeats <- struct{}{}:
default:
}
case names <- dicionario[letra]:
lether := dicionario[letra]
fmt.Printf("Letra: %s \n", lether)

time.Sleep(3 * time.Second) // Simula um tempo de espera para vermos o hearbeats
}
}
}()

return heartbeats, names
}

A continuação deste artigo pode ser lida no iMasters.

Até a próxima, pessoal!

--

--

Rafael Chinaglia
TOTVS Developers

Jornalista/ Editor do iMasters, Gestor de projetos e produtor de conteúdo para TOTVS Developers.