Gen_server and multiple processes

Ulf Wiger <>
Fri Dec 20 17:17:31 CET 2002


On Fri, 20 Dec 2002, hfventer wrote:

>Just to check, you mean to actually spawn a new OTP
>gen_server?  Is this not slow since it has quite a bit of
>overhead. The idea we had was to have one gen_server that
>spawns its own worker threads in the handle_call.

I have submitted a contribution to erlang.org called mdisp.

(when it actually appears depends a bit on how the
contributions moderator works through the Holidays.)

It's based on a concept from the AXD301. The idea is that
you have a permanent process that creates request threads.

The threads themselves are not gen_servers, but one could
easily make a gen_server-compatible "mdisp behaviour", such
that the thread can be programmed like a gen_server.

Just to show what the programming model would look like,
I've added an example behaviour. The callback module
implementing the behaviour needs to implement three
functions: init(Key, State), awake(Key, State),
terminate(Reason,Key,State).

Typically, a "port process" will receive messages from the
outside, do some partial decode, and then call

mdisp:new(MDisp, MDispBehaviour, Key, State)

Subsequent messages can be send to the new instance using

mdisp:send(MDisp, Key, Msg).

The threads can stay up until they're done, or go to sleep
during periods of inactivity (the sleep() function is highly
optimized and "thread safe").

I can submit the whole package (5K) if someone is really
eager to try it out.


-module(mdisp_cb).

-behaviour(mdisp).
-export([init/2, awake/2, terminate/3]).

%% internal exports
-export([f1/2, f2/2]).

-define(write(Fmt, Args), ok=io:format(Fmt, Args)).


init(Key, State = {Fun, S}) ->
    ?write("init(~p, ~p)~n", [Key, State]),
    ?MODULE:Fun(Key, S).

awake(Key, State = {Fun, S}) ->
    ?write("awake(~p, ~p)~n", [Key, State]),
    ?MODULE:Fun(Key, S).


terminate(Reason, Key, State) ->
    exit({Reason, {Key, State}}).


f1(Key, S) ->
    ?write("f1(~p)~n", [S]),
    receive
	Msg ->
	    ?write("f1 ==> ~p~n", [Msg]),
	    f2(Key, S+1)
    after 5000 ->
	    ?write("f1 going to sleep (~p)~n", [S]),
	    mdisp:sleep(mdisp, Key, {f1, S})
    end.

f2(Key, S) ->
    ?write("f2(~p)~n", [S]),
    receive
	this ->
	    ?write("f2 ==> ~p~n", [this]),
	    f1(Key, S+1)
    after 5000 ->
	    ?write("f2 going to sleep (~p)~n", [S]),
	    mdisp:sleep(mdisp, Key, {f2, S})
    end.


-- 
Ulf Wiger, Senior Specialist,
   / / /   Architecture & Design of Carrier-Class Software
  / / /    Strategic Product & System Management
 / / /     Ericsson Telecom AB, ATM Multiservice Networks




More information about the erlang-questions mailing list