Buffer de mensagens em channels

Dando continuidade ao nosso estudo sobre channels, nesse post vamos falar sobre como fazer buffer de mensagens.

Até agora, todos os exemplos que vimos de channels no post “O que são e como utilizar channels” não fazem buffer das mensagens, ou seja, ao escrever uma mensagem no channel, a goroutine que escreveu fica aguardando até que outra goroutine faça a leitura daquela informação. Somente após a leitura é que a goroutine de escrita consegue voltar a escrever algo no channel.

Utilizar buffer de mensagens faz com que a goroutine de escrita seja bloqueado de escrever no channel somente quando o buffer estiver cheio. Já a de leitura só ficará bloqueada quando o buffer estiver vazio. Logo, utilizar um buffer de mensagens pode ajudar com que o trabalho das goroutines seja mais fluido.

Para criar um channel com buffer, tudo que precisamos fazer é passar um parâmetro adicional na sua criação para definir a capacidade máxima.

Leia mais »

O que são e como utilizar channels

Algumas semanas atrás fizemos um post falando sobre o que são e como funcionam as goroutines (link do post). Nesse post, mencionamos sobre os channels quando fizemos um “fix” para que o programa esperasse a execução da goroutine antes de terminar.

No post de hoje vamos aprofundar um pouco sobre o que são os channels e como podemos usá-los.

Podemos pensar em channels como sendo uma espécie de tunel de comunidação entre goroutines, onde uma goroutine consegue enviar informações para outra antes mesmo de terminar sua execução. Nesse mesmo cenário, a goroutine que recebe a informação, ficaria pausada até as informações chegarem.

Quando vamos declarar um channel ou inicializa-lo, precisamos associar um tipo de dado a ele. Esse tipo de dado é o tipo que ele estará apto à transportar entre goroutines.

Leia mais »

Benchmark: API com gorilla mux usando goroutines vs sem goroutines

Já faz um certo tempo que eu queria dedicar algumas horas para testar um cenário onde os dados que uma request deveria apresentar fossem obtidos com goroutines vs sem goroutines.

Finalmente esse dia chegou, mas antes de apresentar os resultados, vamos construir juntos uma simples API onde vamos executar os testes para medir a performance.

O objetivo da request será obter o nome e a quantidade total de pedidos que uma pessoa já realizou.

Para não ter que envolver banco de dados, vamos criar duas variáveis contendo os dados que podemos retornar.

var (
    people = [][]string{
        []string{"1", "Tiago Temporin"},
        []string{"2", "João Silva"},
        []string{"3", "Mateus Cardoso"},
        []string{"4", "Maria Lina"},
        []string{"5", "Camila Manga"},
        []string{"6", "Joice Santos"},
        []string{"7", "Lucas Leal"},
        []string{"8", "Vanessa da Terra"},
        []string{"9", "Mateus de Morais"},
        []string{"10", "Maria Luiza"},
    }

    orders = [][]string{
        []string{"1", "5"},
        []string{"2", "10"},
        []string{"3", "0"},
        []string{"4", "0"},
        []string{"5", "2"},
        []string{"6", "9"},
        []string{"7", "3"},
        []string{"8", "15"},
        []string{"9", "3"},
        []string{"10", "7"},
    }
)
Leia mais »

O que são e como funcionam as Goroutines

Na semana passada explicamos a diferença entre concorrência e paralelismo (link do post), o que serviu de base para o post de hoje, onde vamos explicar as famosas goroutines.

Goroutines são funções ou métodos executados em concorrência. Podemos pensar nelas como uma especie de lightweight thread que são gerenciadas pelo runtime do Go.

Chamamos de lightweight thread pois o custo para sua criação é muito menor quando comparada com um thread de verdade. Outro ponto positivo é que o runtime consegue aumentar ou diminuir a quantidade de goroutines de acordo com a necessidade da aplicação, enquanto o número de thread normalmente é fixo.

Leia mais »