[erlang-questions] Thoughts about server abstraction and process management

Ulf Wiger ulf.wiger@REDACTED
Wed Mar 25 17:34:44 CET 2009

zambal wrote:
> However, assuming that my concerns are valid, lets
 > continue with just the minimal code needed to get
 > an alternative generic server running without
 > worrying about error handling, timeouts, etc.:

You can implement the exact same abstractions
on top of gen_server. See below.

> First, the generic server code
> %% begin yasa.erl (yet another server abstraction)
> -module(yasa).
> -export([new/2, client/1]).
> -export([behaviour_info/1]).
> behaviour_info(callbacks) ->
>     [{init, 1}, {handler, 2}, {terminate, 1}];
> behaviour_info(_Other) ->
>     undefined.
> new(Mod, State) ->
>     client(spawn(fun()-> server(Mod, Mod:init(State)) end)).

new(Mod, State) ->
    client(gen_server:start(?MODULE, {Mod, State}, []))

> client(Pid) ->
>     fun(X) ->
>         Pid ! {self(), X},
>         receive {Pid, Reply} -> Reply end
>     end.

client({ok, Pid}) ->
    fun(X) ->
       gen_server:call(Pid, X)

> server(Mod, State) ->
>     receive
>         {Pid, {stop}} ->
>             Reply = Mod:terminate(State),
>             Pid ! {self(), Reply};
>         {Pid, X} ->
>             {Reply, NewState} = Mod:handler(X, State),
>             Pid ! {self(), Reply},
>             server(Mod, NewState);
>         _ ->
>             server(Mod, State)
>     end.
> %% end yasa.erl

init({Mod, State}) ->
    S = Mod:init(State),
    {ok, S}.

handle_call({stop}, _From, S) ->
    Reply = Mod:terminate(S),
    {stop, Reply, normal, S};
handle_call(X, _From, S) ->
    Mod:handler(X, S).

terminate(_, _) -> ok.

> I'm pretty happy with the result of all this and
 > I can see myself using this solution in small
 > Erlang projects, however I'm very curious
> what other people think of this generic server
 > solution.

I think it's fine, but I would use the gen_server
module in the implementation, as sketched above.

> It's quite easy for processes to become orphaned
 > the same way as it's easy to leak memory in languages
 > with manual memory management.

You can have the server monitor the client, or start
it with a link.

> So I was wondering if there ever have been any ideas
 > about process management like how memory is managed in
 > garbage collected languages?
> I don't know anything about the internals of garbage
 > collectors, but I can imagine that something like
 > reference counted Pids could work: as soon as the last
 > reference to a Pid in an Erlang node is cleared by
> the garbage collector and there's still a process
 > active with that Pid, it should be pretty safe to kill it.

I can recall that the idea has been discussed in the past,
but for better or for worse, it's rather too late for that.
It would probably break existing code in gruesome ways.

Ulf W
Ulf Wiger
CTO, Erlang Training & Consulting Ltd

More information about the erlang-questions mailing list