Skip to content

Instantly share code, notes, and snippets.

@kevinmarquesp
Created June 24, 2024 01:56
Show Gist options
  • Save kevinmarquesp/309f403f4c6ac858dd7d61bb65d8df87 to your computer and use it in GitHub Desktop.
Save kevinmarquesp/309f403f4c6ac858dd7d61bb65d8df87 to your computer and use it in GitHub Desktop.
Um pequeno servidor em Elixir que criei do zero, usando apenas os recursos fundamentais da linguagem. Fiz isso pra estudar e entender plenamente como funciona e, principalmente, pra que serve os tais GenServes. Tentei refletir no código abaixo a API que um GenServer de verdade usaria.
defmodule Counter do
def new(state) do
spawn(Counter, :listener, [state])
end
def arun(pid, args) do # Async run.
send(pid, {:arun, args})
end
def srun(pid, args) do # Sync run.
send(pid, {:srun, self(), args})
receive do
status ->
status
end
end
def listener(state) do
state =
receive do
{:arun, args} ->
{:noreply, state} = handle_arun(args, state)
state
{:srun, from, args} ->
{:reply, status, state} = handle_srun(args, from, state)
send(from, status)
state
end
listener(state)
end
def handle_arun(:display, state) do
IO.puts("[debug] Current counter value: #{state}")
{:noreply, state}
end
def handle_arun({:count, num}, state) do
{:noreply, state + num}
end
def handle_arun(:count, state), do: handle_arun({:count, 1}, state)
def handle_arun(_, state), do: {:noreply, state}
def handle_srun(:get, _from, state) do
status = {:ok, state}
{:reply, status, state}
end
def handle_srun(_, _from, state), do: {:reply, nil, state}
end
counter = Counter.new(0)
Counter.arun(counter, :count)
Counter.arun(counter, :count)
Counter.arun(counter, :count)
Counter.arun(counter, :display)
Counter.arun(counter, {:count, 5})
Counter.arun(counter, {:count, 5})
Counter.arun(counter, {:count, 5})
Counter.srun(counter, :get)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment