continued init (RE: OTP or not to OTP)
Ulf Wiger
etxuwig@REDACTED
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