[erlang-questions] Proper usage of process links vs process monitors?

Ciprian Dorin Craciun ciprian.craciun@REDACTED
Mon Nov 28 19:16:36 CET 2011


    Hello all!

    I've struggled for quite a while now trying to understand when
should I use links, and when should I use monitors.

    Now I'll try to describe what I think the correct usage of links
vs monitors is in some cases, and I would like some input from the
more seasoned Erlang developers.

    So I think I've identified the following scenarios:

    1) client-server (as in `gen_server:call`) -- temporary asymmetric
dependency;
    * we use monitors, as a failure in the client should not propagate
to the server, and also the error is recoverable;
    * usually monitors are short lived for the time the call is outstanding;
    * examples can be found in the `gen_server:call` function;

    2) master-slave (or parent-child, e.g. supervisor trees, web
server socket handlers, etc.) -- permanent symmetric dependency;
    * we use links as a failure on either side should propagate to the
other party; but,
    * usually the parent uses `erlang:process_flag (trap_exit, true)`
to catch the death of children and either ignores, or cleans up and
maybe exits itself;
    * usually the child just dies as a consequence of the propagated
`exit` signal;
    * examples can be found in the `supervisor` module;
    * but there are three sources of bugs here: a) the parent forgets
to kill the children and exists with the `normal` reason (less likely
as the parent is part of a library and is usually written by a highly
skilled and careful developer); b) the child unlinks from the parent
(also less likely as the developer must explicitly unlink its parent);
c) the child is started via a custom `some_module:start_link`
function, which doesn't link the process to its parent;
    * I think monitors would help here (especially on the parent) to
enforce the linked relationship, and especially if we really don't
trust the child code;
    * an `trap_link` or `trap_unlink` would be perfect to make such an
enforcement;

    3) run-time dependency (e.g. one service depends at run-time by
the running of another one, but not the reverse) -- permanent
asymmetric dependency;
    * in this case we again use monitors, as linking would propagate
the client failure to the service, which is not what we want;

    4) inverse run-time dependency -- permanent asymmetric dependency;
    * I think this is a little bit fuzzy for me right now... for
example if I have some library which handles network message
marshaling, and I have a service which depends on it, but there is no
point in the marshaling library to live without the dependent service,
and if the service dies then the library should also die as it has no
purpose; (by library I understand processes spawned by a specific
library);
    * in this case the service links again the library processes and
hopes that these die on unknown 'EXIT' messages;

    As such the guidelines I've found are:
    a) use monitors when you depend on another process but not the
other way around;
    b) use links when you want to propagate exit signals to children
or other "controlled" services;
    c) but if a process ever traps exit signals, it should exit itself
if it receives an exit signal for a process it doesn't know about;
    d) use monitors to enforce links to processes we don't trust;
    e) a library abstracting all these would be really useful -- i.e.
manipulating a data structure holding monitors and links; :)

    Any other considerations?

    Thanks,
    Ciprian.



More information about the erlang-questions mailing list