DEV Community

Cover image for Elixir GenServer?
Willian Frantz
Willian Frantz

Posted on • Edited 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... 👋

Top comments (4)

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!

Collapse
 
diegoleonardo profile image
diegoleonardo

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

Collapse
 
wlsf profile image
Willian Frantz

Vlw maninho!