Monitoring a recv_loop inside a gen_server
Raimo Niskanen
raimo@REDACTED
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