gen_server Counter
Build a stateful server with the gen_server behaviour.
Code
-module(counter).
-behaviour(gen_server).
%% API
-export([start_link/0, inc/0, dec/0, get/0, stop/0]).
%% Callbacks
-export([init/1, handle_call/3, handle_cast/2,
handle_info/2, terminate/2, code_change/3]).
-define(SERVER, ?MODULE).
%% --- API ---
start_link() -> gen_server:start_link({local, ?SERVER}, ?MODULE, 0, []).
inc() -> gen_server:cast(?SERVER, inc).
dec() -> gen_server:cast(?SERVER, dec).
get() -> gen_server:call(?SERVER, get).
stop() -> gen_server:stop(?SERVER).
%% --- Callbacks ---
init(N) -> {ok, N}.
handle_call(get, _From, N) -> {reply, N, N}.
handle_cast(inc, N) -> {noreply, N + 1}.
handle_cast(dec, N) -> {noreply, N - 1}.
handle_info(_Info, N) -> {noreply, N}.
terminate(_Reason, _N) -> ok.
code_change(_Old, N, _Extra)-> {ok, N}.
% Usage:
% {ok, _} = counter:start_link().
% counter:inc(). counter:inc(). counter:get(). %=> 2Explanation
gen_server formalises the tail-recursive server-loop pattern. The module exports an API (start_link, inc, dec, get) that wraps gen_server:call (synchronous, blocks for a reply) or gen_server:cast (asynchronous, fire-and-forget). State flows through init -> handle_call/handle_cast -> terminate. The behaviour directive makes the compiler verify all 6 callbacks are exported with the correct arity.
More Erlang Snippets
Ping-Pong Processes
Two processes pass messages back and forth using spawn and receive.
Supervisor Tree
Define a supervisor that starts workers and restarts them on crash.
Selective Receive with References
Match a specific reply out of many messages using a unique reference.
Links, Exit Trapping & 'Let It Crash'
Use link and trap_exit to detect process death and recover.
Stateful Server via Tail Recursion
Hold mutable state in a process by threading it through recursive calls.
Parallel Map with rpc:pmap
Apply a function to each list element in parallel across processes.