DEV Community

Cover image for Elixir GenServer?
Willian Frantz
Willian Frantz

Posted on • Updated on

Elixir GenServer?

Primeiramente, oi 👋 me chamo Willian, sou desenvolvedor e pretendo usar esse espaço para compartilhar o pouco que aprendi durante esses últimos anos trabalhando com TI. 

Se você é pessoa desenvolvedora back-end e/ou está sempre procurando atualizações, novas tecnologias ou novos conhecimentos, esse texto é para você!

Bom, vem comigo.

Come on!!!

Elixir

Se você ainda não conhece a linguagem de programação Elixir, vou deixar alguns links abaixo que considero como sendo os de maior influência para te dar uma leve noção de sintaxe e semântica, porém nada muito profundo, para não te sobrecarregar. 😄

Links:
https://elixir-lang.org/
https://elixirschool.com/pt

Além disso, pretendo postar mais conteúdos sobre e garantir que seja possível acompanhar essa tecnologia, e entender como ela pode funcionar (ou não) para você!

GenServer

O que seria isso?

Ele é um dos módulos que compõem o pacote OTP (Erlang/BEAM). É possível acessar ele a partir do Elixir graças a interoperabilidade que a linguagem oferece.

Diz-se que o GenServer é um tipo de processo, assim como os demais processos que podem ser gerados no Elixir (ex: Agent, Task). O seu diferencial é que os processos que são criados a partir de sua implementação possuem um estado interno; em outras palavras, você pode criar um processo que roda como um servidor à parte, de forma assíncrona, sem interferir na sua aplicação principal, e esse processo terá um estado interno que poderá ser alterado da forma que for mais adequado para suas necessidades.

Ciclo de vida

O ciclo de vida do seu GenServer tende a funcionar da seguinte maneira: inicia -> loop(chama uma função -> gera um novo estado).

Ex:
Suponhamos que você tenha utilizado o GenServer para implementar uma pilha, seria mais ou menos assim:

diagrama sobre o uso do GenServer

A sua aplicação inicia essa pilha chamando Stack.start() (você está iniciando o seu processo).

Você pode adicionar elementos ou remover elementos utilizando:

stack.push(value) # value = valor que você deseja adicionar.
stack.pop() # retorna o valor que está no topo da pilha.
Enter fullscreen mode Exit fullscreen mode

Os métodos push/1 e pop/0 se encaixam no loop citado acima, onde você está chamando uma função e atualizando o estado interno do seu GenServer.

⚠️ Lembrando que essa pilha irá executar o push/1 de forma assíncrona por ser implementada usando o método handle_cast.

Exemplo implementação de pilha

Seguindo no exemplo do tópico anterior, se estivesse implementando uma pilha, você iria neste caminho:

defmodule Stack do
  use GenServer

  # {...} Outras implementações como init, start_link, etc...

  def handle_call(:pop, _from, [value | state]), do: {:reply, value, state}
  def handle_call(:pop, _from, []), do: {:reply, nil []}

  def handle_cast({:push, value}, state), do: {:no_reply, [value | state]}

  def push(value), do: GenServer.cast(__MODULE__, {:push, value})
  def pop(), do: GenServer.call(__MODULE__, :pop)
end

Enter fullscreen mode Exit fullscreen mode

E isso rodaria mais ou menos assim:

exemplo executando pilha, formato GIF

Curiosidades

O Discord atualmente utiliza Elixir e resolve alguns de seus problemas técnicos utilizando GenServer. Um bom exemplo disso é a implementação de semaphores que foi feito para tratar o gerenciamento dos processos, link: https://github.com/discord/semaphore.

Além disso, existem libs do próprio ecossistema do Elixir que utilizam GenServer, um bom exemplo disso seria a própria lib do kafka_ex, que conecta a sua aplicação ao seu serviço Apache Kafka.

Conclusão

O GenServer é muito utilizado no dia-a-dia de um desenvolvedor Elixir, as vezes até mesmo de forma inconsciente (em libs, frameworks, etc). Por isto, é sempre bom conhecer e saber que ele existe e como ele funciona por baixo dos panos.

Deixarei aqui um repositório com algumas implementações básicas de estruturas de dados:

GitHub logo WLSF / data_structures_ex

Repo to implement data structures using Elixir GenServer

Estruturas de dados usando GenServer (Elixir)

Ex de como executar:

iex
$ Stack.start_link
$ Stack.push 10
$ Stack.pop
-> 10

Repositório do texto: Elixir GenServer?

Por hoje é só, até a próxima... 👋

Latest comments (4)

Collapse
 
diegoleonardo profile image
diegoleonardo

Bem didático o post Will! Parabéns mano! =)

Collapse
 
wlsf profile image
Willian Frantz

Vlw maninho!

Collapse
 
pedromcorreia profile image
Pedro Correia

Maneirissimo Will!! Seria maneiro colocar exemplos de aplicabilidade pra genservers. Tipo quais informações são validar persistirem em estados e quais não. Exemplo é uma informacao de um usuario sobre dados iniciados na sessao. Ja valores tipo inicio de uma transferência de valores acaba que vai onerar sua maquina! Fora isso animal!! :D

Collapse
 
wlsf profile image
Willian Frantz

Que dahora, vlw pela sugestão mano!