Welcome to gen_leader

Version: 1.0

Authors: Ulf Wiger (ulf.wiger@ericsson.com), Thomas Arts (thomas.arts@ituniv.se).

A leader election behaviour modeled after gen_server.

This behaviour intends to make it reasonably straightforward to implement a fully distributed and fault-tolerant server with master-slave semantics.

The leader election algorithm used is designed to find a leader in constant time. A prerequisite is that all candidates are known from the beginning (but obviously, they do not all need to be alive.)

The gen_leader behaviour supports nearly everything that gen_server does (some functions, such as multicall() and the internal timeout, have been removed), and adds a few callbacks and API functions to support leader election etc.

Example

Included is an example program, a global dictionary, gdict, based on the modules gen_leader and dict. The callback implementing the global dictionary is called 'test_cb', for no particularly logical reason.

gdict

gdict consists of 50 lines of code, essentially emulating the interface of dict.erl. The "magic" in gdict is performed by two macros:

-define(store(Dict,Expr,Legend),
        gen_leader:leader_call(Dict, {store, fun(D) ->
                                                     Expr
                                             end})).

-define(lookup(Dict, Expr, Legend),
        gen_leader:call(Dict, {lookup, fun(D) ->
                                               Expr
                                       end})).

(Legend was a means to hook in some debugging info, but is currently not used.)

Using these macros, the update functions in dict.erl can be mapped to a set of gen_leader processes maintaining a replicated dictionary:

store(Key, Value, Dict) ->
    ?store(Dict, dict:store(Key,Value,D), store).

fetch(Key, Dict) -> ?lookup(Dict, dict:fetch(Key,D), fetch).

... and so on.

Instantiating a global dictionary is done via gdict:new/3:

new(Name, Candidates, Workers) ->
    gen_leader:start(Name,Candidates, Workers, test_cb, dict:new(), []).

test_cb

test_cb consists of 49 lines of code, and is the gen_leader callback module supporting gdict. The "magic" is performed by the following lines:

handle_leader_call({store,F}, From, Dict, E) ->
    NewDict = F(Dict),
    {reply, ok, {store, F}, NewDict};
...
from_leader({store,F}, Dict, E) ->
    NewDict = F(Dict),
    {ok, NewDict}.

handle_call({lookup, F}, From, Dict) ->
    Reply = F(Dict),
    {reply, Reply, Dict}.

Note that updates are served through the leader, using gen_leader:leader_call/2 and handle_leader_call/4 respectively, while lookups are served locally, using gen_leader:call/2 and handle_call/3. More details are found in test_cb.

Callbacks

Documentation of the required callbacks can be found in the example callback test_cb.


Generated by EDoc, Feb 18 2008, 06:49:48.