Reading — step 1 of 5
Learn
~1 min readOTP Behaviours
gen_server is OTP's standard behaviour for stateful server processes. Implements the receive-loop pattern with hooks for sync call, async cast, and lifecycle.
-module(counter).
-behaviour(gen_server).
-export([start_link/0, increment/0, value/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
%% Client API
start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, 0, []).
increment() -> gen_server:cast(?MODULE, increment).
value() -> gen_server:call(?MODULE, get).
%% Server callbacks
init(Initial) -> {ok, Initial}.
handle_call(get, _From, State) -> {reply, State, State}.
handle_cast(increment, State) -> {noreply, State + 1}.
handle_info(_Msg, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.
Two-part split:
- Client API — what callers use (
start_link,increment,value) - Server callbacks — internal protocol (
init,handle_call, ...)
This is THE Erlang convention. Hides the gen_server protocol behind a clean API.
Return shapes for callbacks:
%% handle_call:
{reply, Reply, NewState}
{reply, Reply, NewState, Timeout}
{reply, Reply, NewState, hibernate}
{noreply, NewState} %% no reply yet — manual reply later
{stop, Reason, Reply, NewState}
%% handle_cast:
{noreply, NewState}
{stop, Reason, NewState}
call vs cast:
call— synchronous, caller waits for reply. Use for queries.cast— asynchronous, returnsokimmediately. Use for fire-and-forget actions.
Why gen_server over hand-rolled receive loops:
- Tested protocol — handles caller crashes, monitors, timeouts
- Standard message format — tools (observer, recon) can introspect
- Plays nicely with supervisors
- Hot code reload via
code_change
For Judge0 — the build won't compile a -behaviour module unless gen_server is present (it is — part of OTP). The escript-style template works:
-module(main).
-export([main/1]).
%% gen_server can be defined inline as a separate module... but for one-shot scripts,
%% manual receive loops are usually simpler.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…