Erlang and process_flag(trap_exit, true)
Asked Answered
R

3

24

After watching the Pragmatic Studio screen casts on Erlang, the last video on Supervisors mentioned that in order for a supervisor to get a notification about one of its children so it can properly restart it, the child should register with process_flag(trap_exit, true). Perhaps I just misunderstood the author (and chances are VERY high that I did misunderstand), but I thought supervisors automagically know when their children die (probably through spawn_link or something similar in the background). Is this really necessary? When should one use process_flag(trap_exit, true) in a real world case because the documentation explicitly states the following:

http://www.erlang.org/doc/man/erlang.html#process_flag-2

process_flag(trap_exit, Boolean)

When trap_exit is set to true, exit signals arriving to a process are converted to {'EXIT', From, Reason} messages, which can be received as ordinary messages. If trap_exit is set to false, the process exits if it receives an exit signal other than normal and the exit signal is propagated to its linked processes. Application processes should normally not trap exits.``

Responsory answered 16/7, 2011 at 21:50 Comment(1)
The need for setting the trap_exit flag in an OTP application is indeed an exceptional situation. Most OTP applications don't need setting the trap_exit flag explicitly as supervisors are designed to handle them correctly according to child specifications.Holiday
C
41

You have 3 idioms:

1/ I don't care if my child process dies:

spawn(...)

2/ I want to crash if my child process crashes:

spawn_link(...)

3/ I want to receive a message if my child process terminates (normally or not):

process_flag(trap_exit, true),
spawn_link(...)

Please see this example and try different values (inverse with 2 or 0 to provoke an exception, and using trap_exit or not):

-module(play).
-compile(export_all).

start() ->
    process_flag(trap_exit, true),
    spawn_link(?MODULE, inverse, [2]),
    loop().

loop() ->
    receive
        Msg -> io:format("~p~n", [Msg])
    end,
    loop().

inverse(N) -> 1/N.
Changchangaris answered 16/7, 2011 at 23:17 Comment(3)
Re #1 - I often think that, but then I realize I want that process to exit when my system shuts down. That's what temporary supervised children are for.Revolving
I think so too. I think @rvirding has given the right answer to the questionAgnomen
My reason was just to point out that this doesn't answer the actual question. The OP asks when to use trap_exit in the real world. Your answer details the different types of linking to a process.Unbeatable
S
33

Supervisors use links and trap exits so they can keep track of their children and restart them when necessary. Child processes do not have to trap exits to be properly managed by their supervisors, indeed they should only trap when they specifically need to know that some process to which they are linked dies and they don't want to crash themselves.

The OTP behaviours are able to properly handle supervision if they are trapped or not trapped.

Slider answered 17/7, 2011 at 1:14 Comment(0)
F
21

In Erlang, processes can be linked together. These links are bi-directional. Whenever a process dies, it sends an exit signal to all linked processes. Each of these processes will have the trapexit flag enabled or disabled. If the flag is disabled (default), the linked process will crash as soon as it gets the exit signal. If the flag has been enabled by a call to system_flag(trap_exit, true), the process will convert the received exit signal into an exit message and it will not crash. The exit message will be queued in its mailbox and treated as a normal message.

If you're using OTP supervisors, they take care of the trap_exit flags and details for you, so you don't have to care about it.

If you're implementing a supervision mechanism, which is probably what the screen-cast is about (haven't seen it), you will have to take care of the trap_exit thing.

Freitas answered 21/7, 2011 at 10:19 Comment(1)
to turn a process into a system process you call: process_flag(trap_exit, true)Cidevant

© 2022 - 2024 — McMap. All rights reserved.