[erlang-questions] gen_leader

Ulf Wiger ulf.wiger@REDACTED
Thu Jun 25 07:54:55 CEST 2009

wde wrote:
> the 'test_cb' module provided with the gen_leader module
 > specify a {noreply,Dict} for handle_info/2 and
 > handle_cast/2 whereas  gen_leader use handle_common_reply
 > to handle callback response for handle_info/2 and
 > handle_cast/2 api.
> Why handle_info and handle_cast do not accept classical return
 > values (gen_server like :
 > {noreply,NewState} | {noreply,NewState,Timeout}
 > | {noreply,NewState,hibernate} ) ?

First of all, the {noreply,NewState,hibernate} was
added after gen_leader was developed, so it would
be possible to add.

The {noreply, NewState, Timeout} becomes more
complicated with gen_leader than with gen_server,

With gen_server, the Timeout has the obvious, but
perhaps yet sometimes confusing semantics:

loop(Parent, Name, State, Mod, Time, Debug) ->
     Msg = receive
               Input ->
           after Time ->
     decode_msg(Msg, ...).

This means that the wait will be reset any time
the server receives a system message, which is
perhaps not what the user intended, but still a rare
enough occurence not to matter much.

With gen_leader, however, the election protocol
will generate more traffic, as candidates and
workers come and go, so the 'false' timer resets would
be more common. It was our assumption back then that
the Timeout value in the reply had only limited usefulness,
and wouldn't be missed by many - therefore we chose not
to venture into the more complicated timeout handling
that would have been needed for gen_leader.

> Buffered calls never deleted ? 
> The following function handle_msg/4 in gen_leader :
>  handle_msg({Ref, {leader,reply,Reply}} = Msg, Server, Role,#election{buffered = Buffered} = E) ->
>     {value, {_,From}} = keysearch(Ref,1,Buffered),
>     NewServer = reply(From, {leader,reply,Reply}, Server, Role, E#election{buffered = keydelete(Ref,1,Buffered)}),
>     loop(NewServer, Role, E, Msg);
> It seems that we loop without deleting the old reference. I modify the function like that :
> handle_msg({Ref, {leader,reply,Reply}} = Msg, Server, Role,#election{buffered = Buffered} = E) ->
>     {value, {_,From}} = keysearch(Ref,1,Buffered),
>     E1 = E#election{buffered = keydelete(Ref,1,Buffered)},
>     NewServer = reply(From, {leader,reply,Reply}, Server, Role, E1),
>     % keep the new opaque election in the loop 
>     loop(NewServer, Role, E1, Msg);

A bug indeed. Thanks. Hopefully one of the people working on
the gen_leader revival on github will pick it up and fix it.

Perhaps you could also join that effort?


Ulf W
Ulf Wiger
CTO, Erlang Training & Consulting Ltd

More information about the erlang-questions mailing list