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.
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:
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.
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
E isso rodaria mais ou menos assim:
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:
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)
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
Que dahora, vlw pela sugestão mano!
Bem didático o post Will! Parabéns mano! =)
Vlw maninho!