[erlang-patches] gen_server broken !!

Claes Wikstrom klacke@REDACTED
Thu Feb 21 15:04:04 CET 2008


This is something that has bothered me for quite some time.
There is no way to write a function which calls
gen_server:start_link() that then returns a nice controlled error.

If we return ignore from out init() callback, there is no way
to propagate a Reason.

If we return stop or {stop, Reason} we get all sorts of
bad behavior including ugly printouts in the error log.
Furthermore if we are
   a) trapping exits - we get an EXIT signal in our inbox from
      a Pid we've never heard of
   b) Not trapping EXITs, we die

All I want is to silently return

say we have in myserver.erl

start_link() ->
     gen_server:start_link(?MODULE, [], []).

....

init([]) ->
    case file:open("FOO") of
       {ok, Fd} ->
          {ok, mkstate(Fd)};
       {error, Reason} ->
          {stop, Reason}
    end.

It means that myserver:start_link() really sucks. It has
different behavior whether the caller traps exit or not.

The solution is to have

init([]) ->
    case file:open("FOO") of
       {ok, Fd} ->
          {ok, mkstate(Fd)};
       {error, Reason} ->
          {ignore, Reason}
    end.



Index: gen_server.erl
===================================================================
--- gen_server.erl      (revision 15284)
+++ gen_server.erl      (working copy)
@@ -31,6 +31,7 @@
  %%%     ==> {ok, State}
  %%%         {ok, State, Timeout}
  %%%         ignore
+%%%         {ignore, Reason}
  %%%         {stop, Reason}
  %%%
  %%%   handle_call(Msg, {From, Tag}, State)
@@ -285,7 +286,12 @@
             exit(Reason);
         ignore ->
             proc_lib:init_ack(Starter, ignore),
+            unlink(Parent),
             exit(normal);
+        {ignore, Reason} ->
+           proc_lib:init_ack(Starter, {ignore, Reason}),
+            unlink(Parent),
+           exit(normal);
         {'EXIT', Reason} ->
             proc_lib:init_ack(Starter, {error, Reason}),
             exit(Reason);




/klacke



More information about the erlang-patches mailing list