GenServer is the OTP behaviour for building stateful server processes without manually implementing recursive loops, state management, and message passing. The Elixir GenServer module wraps the Erlang standard-library :gen_server implementation, which supplies the underlying generic-server machinery. section 6.0 section 6.2
A callback module commonly defines:
- init/1 establishes the initial state passed to later callbacks. section 6.2.3
- handle_cast/2 processes fire-and-forget requests and returns a new state. section 6.2.3 section 6.3
- handle_call/3 processes synchronous requests and returns a reply plus updated state. section 6.2.3 section 6.3
- handle_info/2 handles other messages delivered to the server process. section 6.3
KeyValueStore
A small server can keep a map as its state: init/1 returns {:ok, %{}}, a cast handles {:put, key, value} with {:noreply, new_state}, and a call handles {:get, key} with {:reply, value, state}. Public functions hide the protocol behind KeyValueStore.put/3 and KeyValueStore.get/2. GenServer.call/3 waits for a response, timing out after five seconds by default; GenServer.cast/2 returns immediately. section 6.2.3
The GenServer loop owns the process lifecycle, while callbacks execute in the server process and transform the current state into the next state. GenServer.start/2 does not return until init/1 finishes. Servers can also receive a registered local name, allowing clients to call them without knowing their PID. The @impl GenServer attribute catches callback arity mistakes at compile time. section 6.2.5 section 6.2.6
Listing 6.9 Implementing GenServer callbacks (key_value_gen_server.ex)
defmodule KeyValueStore do
use GenServer
def init(_) do
{:ok, %{}}
end
def handle_cast({:put, key, value}, state) do
{:noreply, Map.put(state, key, value)}
end
def handle_call({:get, key}, _, state) do
{:reply, Map.get(state, key), state}
end
end
Browse the complete callback implementation for the KeyValueStore example. section 6.2.3
