Last active
June 24, 2024 02:00
-
-
Save kevinmarquesp/41a8a690d784b8a808450ec6e57edd08 to your computer and use it in GitHub Desktop.
Lista de conceitos que fui escrevendo e colando no terminal rodando om IEX pra entender, certinho, como funciona um GenServer por baixo dos panos.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Concept 1: | |
# Elixir can spawn process to run functions. | |
spawn(fn -> | |
"Hello world!" | |
end) | |
# Concept 2: | |
# Elixir can send messages to other process, including the current IEX one. | |
# At the same time, it can stop the runtime and wait to recieve a message | |
# sent to other process. | |
mypid = self() | |
send(mypid, {:info, "Hello world!"}) | |
receive do | |
{:info, msg} -> | |
IO.puts(msg) | |
end | |
# Alternative that waits some seconds before sending a message. | |
mypid = self() | |
Process.send_after(mypid, {:info, "Hello world!"}, 5000) | |
receive do | |
{:info, msg} -> | |
IO.puts(msg) | |
end | |
# Therefore: | |
# It's possible to create a module that can send stuff to other process and | |
# receive messages at the same time. | |
defmodule Person do | |
@doc """ | |
When created a new function, it will run the listen function of the package | |
specified **in background**, it will return the PID of that process. | |
""" | |
def new() do | |
spawn(Person, :listen, []) | |
end | |
@doc """ | |
This will keep listening to messages and executing some code based on what | |
is received. That's why it was the function choosen to be ran in a background | |
process. | |
""" | |
def listen() do | |
receive do | |
{:msg, message} -> | |
## threat this block as an method of an object. | |
IO.puts("Someone said to me \"#{message}\" right now!") | |
end | |
listen() | |
end | |
end | |
# User's API for that kind of module. | |
bob_pid = Person.new() | |
send(bob_pid, {:msg, "Hello bob!"}) | |
# Maintaining state: | |
# Even with Elixir not having any kind of OOP, it can store state (a.k.a. | |
# data) throught recursion -- pay attention in the listen() recursion call | |
# on the previous module. | |
defmodule Counter do | |
def new(start) do | |
spawn(Counter, :listen, [start]) | |
end | |
def listen(counter) do | |
counter = | |
receive do | |
:count -> | |
counter + 1 | |
:show -> | |
IO.puts(counter) | |
counter | |
end | |
listen(counter) | |
end | |
end | |
# User's API for that kind of module. | |
counter = Counter.new(0) | |
send(counter, :count) | |
send(counter, :count) | |
send(counter, :count) | |
send(counter, :show) | |
# Therefore: | |
# As you can see, this functions is the only ones required to achieve the | |
# behavior that we want. But how about get information from this sub | |
# processes? It's also possible using that same send/receive strategy. | |
defmodule Counter do | |
def new(start) do | |
spawn(Counter, :listen, [start]) | |
end | |
def listen(counter) do | |
counter = | |
receive do | |
{:count, from, num} -> | |
send(from, {:ok, "Successfuly received new value."}) | |
counter + num | |
{:get, from} -> | |
send(from, counter) | |
counter | |
end | |
listen(counter) | |
end | |
# Below, are the user's API function callbacks. | |
def count(pid, num) do | |
send(pid, {:count, self(), num}) | |
receive do | |
{:ok, status} -> | |
{:ok, status} | |
end | |
end | |
def get(pid) do | |
send(pid, {:get, self()}) | |
receive do | |
num -> | |
num | |
end | |
end | |
end | |
# User's API for that kind of module. | |
counter = Counter.new(0) | |
Counter.count(counter, 1) | |
Counter.count(counter, 0) | |
Counter.count(counter, 2) | |
Counter.get(counter) | |
# Finial notes: | |
# The asunc functions is just the user's API callbacks from the previous | |
# module, but without the receive action -- which means that those functions | |
# will execute and wont stop the run time waiting for a response. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment