gen_server broken !!

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

gen_server broken !!

Claes Wikström

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


Reply | Threaded
Open this post in threaded view
|

gen_server broken !!

Matthew Dempsky-3
On 2/21/08, Claes Wikstrom <klacke> wrote:
>  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.

I can imagine uses for that, but I think crying "gen_server broken !!"
over this is a bit sensational.


Reply | Threaded
Open this post in threaded view
|

gen_server broken !!

Claes Wikström
Matthew Dempsky wrote:
> On 2/21/08, Claes Wikstrom <klacke> wrote:
>>  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.
>
> I can imagine uses for that, but I think crying "gen_server broken !!"
> over this is a bit sensational.

I know - I chose the mail title mostly for fun. Nevertheless gen_server
as it is now is not suitable for transient gen_servers where the
init() cb may return an error.
If this is your usecase it is better to roll your own server - which
is boring.

This patch can be made completely backwards compat and should be
added in some form.


/klacke