[erlang-questions] Where can I use gen_server?

fess fess-erlang@REDACTED
Fri Apr 3 18:48:33 CEST 2009


You are starting one gen_server, that itself responds to the messages  
sent via gen_server cast/call in serial, so if it crashes it will no  
longer get to any of the other things in it's message queue.

I think you probably want to spawn a new process in your handle_cast,   
[ which is what your first email mentioned you wanted the server to  
do,  handle connections then spawn a process to handle them. ]

right now,  you call test2()  the server handles that message and  
crashes.    there is no longer a server to handle the message sent by  
test(),  messages  sent to non existent processes silently go into the  
void. [ not to mention that gen_server:cast always returns ok.  ]

if you change the handle_cast(test, ...  to:


handle_cast(test, State) ->
         spawn( fun () ->
    	         timer:sleep(3000),
	         io:format("asdasd")
                end ),
	   {noreply, State};

and leave test2() alone so that it crashes the gen_server, then your  
test() casts will cause the gen_server to spawn a new proc to sleep  
and won't be effected by a gen_server crash.

then you can call

start(), test(), test2()

which should get your io:format through.   [ unless io:format goes  
somewhere else,  then you can call io:format/3 but I usually just use  
error_logger:error_report/1 ]
ie,  server starts,   gets a test message and spawns a proc to sleep  
and io:format, then gets a test2 message and crashes,  the spawned  
proc continues because it's not linked to the parent and later does  
it's io:format.

I think maybe that answers what your asking. if not,  ask again. :)

You should definitely use gen_server, or you'll probably end up  
approximating it.   It's one of those things that's trivial once you  
got what it's doing.   someone also posted gen_serv I think that  
reduced the amount of boilerplate you have to write.

hope that helps.

--fess


On Apr 3, 2009, at 8:52 AM, ryeguy wrote:

> All I'm trying to do is find out
> why all requests are taken down with the gen_server when it crashes?



On Apr 1, 2009, at 7:34 PM, ryeguy wrote:

> Well why doesn't this work then?
>
> start()               -> gen_server:start({global, ?MODULE}, ?MODULE,
> [], []).
> stop()                -> gen_server:call({global, ?MODULE}, stop).
> test()                -> gen_server:cast({global, ?MODULE}, test).
> test2()                -> gen_server:cast({global, ?MODULE}, test2).
>
> init([]) ->process_flag(trap_exit, true),
>    {ok, 0}.
>
> handle_cast(test, State) ->
> 	timer:sleep(3000),
> 	io:format("asdasd"),
> 	{noreply, State};
> handle_cast(test2, State) ->
> 	timer:sleep(3000),
> 	3=4,                 %%% deliberate error
> 	{noreply, State}.
>
> handle_call(stop, _From, State) ->
>    {stop, normal, stopped, State};
> handle_call(test2, _From, State) ->
> 	3=4,
>    {noreply, State}.
>
> handle_info(_Info, State) ->
>    {noreply, State}.
>
> terminate(_Reason, _State) ->
>    ok.
>
> code_change(_OldVsn, State, _Extra) ->
>    {ok, State}.
>
> When I call test2() then call test(), test2 (obviously) crashes, but
> test() appears to be terminated too.

--fess






More information about the erlang-questions mailing list