Gen_server and multiple processes
Ulf Wiger
etxuwig@REDACTED
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