Monitoring a recv_loop inside a gen_server

Raimo Niskanen <>
Mon Jun 17 09:17:04 CEST 2002


%% A little skeleton as a possible path to choose.
%%
%% This has never been compiled.

-module(applio).
-behaviour(gen_server).

%% Replace 'applio_name' and 'args' with something better.

%% API

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

start() ->
    gen_server:start(applio_name, ?MODULE, args, []).

%% Callbacks

init(args) ->
    process_flag(trap_exit, true),
    State = spawn_link(fun () -> recv_loop() end),
    {ok, State}. %% Augument state if necessary

handle_info({'EXIT, State, Reason}, State) ->
    {stop, Reason, undefined};
%% Other handle_info/2 clauses

%% End of example

The function start_link/1 (and start/1) are API functions and as such
called from some unknown process. If they are to be called from a
supervisor (in a supervision tree in an application), start_link/1 is
certainly the one to choose. Then the supervisor will notice when the
gen_server dies and can take action. These functions call
gen_server:start* that spawns the actual applio gen_server process.

The function applio:init/1 is called in the gen_servers process context,
and it will live on after the start of the gen_server, so it should
spawn_link() the recv_loop process. 

The process_flag(trap_exit, true) and handle_info('EXIT', ...) stuff is
a way for the gen_server to detect that the recv_loop dies and do
something (or just die, passing the problem to the supervisor above).

/ Raimo Niskanen, Erlang/OTP, Ericsson AB



Bruce Fitzsimons wrote:
> 
> People,
> 
> More questions...thanks to everyone who replied last time and I'm sorry if I
> didn't reply to everyone.
> 
> I am using a udp recv_loop in conjunction with a gen_server, where the
> gen_server:init starts the loop, and the loop processing makes calls to the
> gen_server through its interface. I forget where I learnt this design
> pattern, but it works well..
> 
> However, from time to time I create bugs which cause the recv_loop to crash.
> The recv_loop has been started as an independent process (spawn), so when it
> dies no one notices.
> 
> I believe the reason I did not use spawn_link in the gen_server:init was
> because the init seemed to be run from an independent process that stopped,
> which killed the loop. The internals of gen_server are a bit of a mystery to
> me. Does this sound accurate?
> 
> I'm making my server an application, and adding supervision, so I thought I
> should fix this at the same time. I guess I could spawn_link the recv_loop
> in the gen_server api (eg if module aplio is a geb_server, then
> aplio:start_link() could start the loop and the gen_server) but the loop is
> related to the gen_server, not the parent process, so it doesn't sound right
> to me.
> 
> All help appreciated.
> 
> /Bruce



More information about the erlang-questions mailing list