Nathaniel Waisbrot
Nathaniel Waisbrot

Reputation: 24523

Correct way to shut down when trapping exits?

I have a gen_server where I trap exits with

%% worker.erl
% ...
init(args) ->
  process_flag(trap_exit, true)
  % ...

handle_info({'EXIT', SpecialPid, Reason}, SpecialPid) ->
  % terminate
  exit(normal);
handle_info({'EXIT', _NormalPid, _Reason}, SpecialPid) ->
  % ignore     
  {noreply, SpecialPid}.

I want to be able to shut down the supervision tree over this gen_server:

%% sup_sup.erl
% ...
  supervisor:terminate_child(self(), worker_sup),
% ...

When I run, I can terminate the worker. However, I get OTP errors as if the process termination was unexpected. I also tried exit(normal) and returning {stop, normal, State} and {stop, shutdown, State} which all produce the same effect.

What is the correct way to emulate OTP's behavior during a shutdown, while still trapping exits in other cases?

Upvotes: 2

Views: 240

Answers (1)

ITChap
ITChap

Reputation: 4752

You just need to return {stop, normal, State) from your handle_info/2. You might still get info/error messages from your supervisor depending on the child specifications you use for this process.

If you expect your process to stop after finishing its job and not being restarted, you should use restart => transient in the child specs. This way the process will be restarted if it exits with any other reason than normal. But you shouldn't get any message when using {stop, normal, State}.

Upvotes: 0

Related Questions