continued init (RE: OTP or not to OTP)

Ulf Wiger <>
Mon Mar 3 14:25:01 CET 2003


On Mon, 3 Mar 2003, Ulf Wiger wrote:

>The place where this is preferrable to self() ! continue,
>is for example during process restarts, when clients are
>active and may succeed in calling the server before you
>have time to send to yourself. It is very difficult to
>close this hole entirely, and the above "hack" eliminates
>the problem (introducing a less serious "double ack"
>problem, which can be handled in supervisor.erl)
>
>The Better Solution will probably be something along the
>lines of init/1 returning {continue, fun()}, or something.
>Stay tuned (or take a look at my attached suggestion for a
>patch -- my way of trying to appease the OTP Gods after
>having promoted dirty hacks to the public... ;-)


BTW, I tested my patch with the following callback:

-module(gen_server_test).

-behaviour(gen_server).

...

start_link() ->
    spawn(fun() -> spray(?MODULE,600) end),
    {ok,Pid} = gen_server:start_link({local, ?MODULE}, ?MODULE, [], []),
    Pid ! foo,
    {ok,Pid}.

spray(Name, N) when N > 0 ->
    catch Name ! {evil_message,N},
    spray(Name,N-1);
spray(Name,_) ->
    ok.

init([]) ->
    {continue, fun() -> continued_init() end}.

continued_init() ->
    self() ! i_am_here,
    {ok, #state{}}.

handle_info(Info, State) ->
    io:format("*** Info: ~p~n", [Info]),
    {noreply, State}.


I then tested it, and got the following printout:

20> gen_server_test:start_link().
*** Info: {evil_message,101}
*** Info: {evil_message,100}
{ok,<0.110.0>}
*** Info: {evil_message,99}
*** Info: {evil_message,98}
*** Info: {evil_message,97}
*** Info: {evil_message,96}
*** Info: {evil_message,95}
*** Info: {evil_message,94}
*** Info: {evil_message,93}
*** Info: {evil_message,92}
*** Info: {evil_message,91}
*** Info: {evil_message,90}
*** Info: {evil_message,89}
*** Info: {evil_message,88}
*** Info: {evil_message,87}
*** Info: {evil_message,86}
*** Info: {evil_message,85}
*** Info: {evil_message,84}
*** Info: {evil_message,83}
*** Info: {evil_message,82}
*** Info: {evil_message,81}
*** Info: {evil_message,80}
*** Info: i_am_here
*** Info: {evil_message,79}
*** Info: {evil_message,78}
*** Info: {evil_message,77}
*** Info: {evil_message,76}
*** Info: {evil_message,75}
*** Info: {evil_message,74}
*** Info: {evil_message,73}
*** Info: {evil_message,72}
*** Info: {evil_message,71}
*** Info: {evil_message,70}
*** Info: foo
*** Info: {evil_message,69}
*** Info: {evil_message,68}
...

I was able to squeeze in 23 unwanted messages before the one
that I casted to myself in the init/1 function, and another
10 before the message that came from the start_link()
function. Not a realistic scenario, mind you, but fairly
illustrative.

/Uffe
-- 
Ulf Wiger, Senior Specialist,
   / / /   Architecture & Design of Carrier-Class Software
  / / /    Strategic Product & System Management
 / / /     Ericsson AB, Connectivity and Control Nodes




More information about the erlang-questions mailing list