Skip to content
Erlang

gen_server Counter

Build a stateful server with the gen_server behaviour.

By EZ4Code Team
gen_serverotpbehaviour

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().  %=> 2

Explanation

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