Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The error you are seeing is actually not an error but an <strong>error report</strong> generated by <a href="https://github.com/basho/lager" rel="noreferrer">lager</a>. This report seems to be caused by <strong>a bug in poolboy</strong>.</p> <p>You can either:</p> <ul> <li>Fix the bug and submit a patch to poolboy developers.</li> <li>Safely ignore the report.</li> <li>Manually terminate your workers on exit.</li> </ul> <p>What is supposed to happen when you stop an OTP application is that the supervision tree is used to terminate all processes, preferably gracefully. The default way to do it is to send supervised processes a <code>shutdown</code> signal, and if this doesn't work after a while, to brutally kill them. You never get any report when everything goes smoothly.</p> <p>There are two Erlang subtleties to understand the bug:</p> <ol> <li>Processes can be <a href="http://erlang.org/doc/man/erlang.html#link-1" rel="noreferrer"><strong>linked</strong></a>, which means that when one process terminates abnormally (i.e. with a reason other than <code>normal</code>), all linked processes are terminated with the same reason. This primitive is the basis of OTP supervision.</li> <li>A process can <a href="http://erlang.org/doc/man/erlang.html#process_flag-2" rel="noreferrer"><strong>trap exit signals</strong></a> (or <em>trap exits</em>), which means it receives exit signals as regular messages instead of being terminated (including <code>normal</code> which wouldn't terminate it, but excluding <code>kill</code> which will terminate it unconditionally).</li> </ol> <p>Links combined with trapping exits are often used to monitor termination of processes, with the additional benefit of terminating monitored processes when the monitoring process terminates. For example, if a supervisor terminates, its children shall be terminated. An asymmetrical <a href="http://erlang.org/doc/man/erlang.html#monitor-2" rel="noreferrer"><code>monitor</code></a> mechanism also exists.</p> <p>Here, your supervisor (implementing test_sup behavior) is terminated with the reason <code>shutdown</code>, as it should be. The supervisor behavior actually traps exits and when it receives the <code>shutdown</code> signal, it tries to terminate its children according to their shutdown strategy. Here, you use the default strategy, which is to send children the <code>shutdown</code> signal as a first attempt. So your supervisor sends the <code>shutdown</code> signal to its only child.</p> <p>Poolboy introduces its magic here, and the child of your supervisor is actually a <code>gen_server</code> with <a href="https://github.com/devinus/poolboy/blob/master/src/poolboy.erl" rel="noreferrer"><code>poolboy</code></a> callback module. It should shut down the pool and terminate gracefully.</p> <p>This module is linked to the <a href="https://github.com/devinus/poolboy/blob/1.0.1/src/poolboy.erl#L111" rel="noreferrer">pool supervisor</a>, but also to <a href="https://github.com/devinus/poolboy/blob/1.0.1/src/poolboy.erl#L237" rel="noreferrer">the workers</a>. This surprising implementation choice is probably that a crash of the pool (the poolboy <code>gen_server</code>) shall terminate the workers. However, this is the source of the bug, and an asymmetric monitor would probably make more sense. Since the supervisor is already linked to the poolboy <code>gen_server</code>, a termination of the <code>poolboy</code> process will eventually lead to a termination of the workers anyway.</p> <p>The consequence of linking to the workers is that they also get the <code>shutdown</code> exit signal which was initially directed to the <code>poolboy</code> process. And they are terminated. This termination is considered abnormal by the workers' supervisor (implementing <code>poolboy_sup</code> callback) since it did not send the signal itself. As a result, the supervisor reports the shutdown, which is logged by lager here.</p> <p>The fact that <code>poolboy</code> <a href="https://github.com/devinus/poolboy/blob/1.0.1/src/poolboy.erl#L105" rel="noreferrer">traps exits</a> does not prevent the propagation of the <code>shutdown</code> signal. The process is not terminated immediately when it receives the signal but it receives it as a message. <code>gen_server</code> intercepts this message, calls <code>terminate/2</code> callback function and then <a href="https://github.com/erlang/otp/blob/OTP_R16B02/lib/stdlib/src/gen_server.erl#L728" rel="noreferrer">terminates with <code>shutdown</code></a>, eventually propagating the signal to all linked processes.</p> <p>If avoiding to <a href="https://github.com/devinus/poolboy/blob/1.0.1/src/poolboy.erl#L237" rel="noreferrer">link to workers</a> is not an option, a way to fix this bug would be to unlink all workers in the <a href="https://github.com/devinus/poolboy/blob/1.0.1/src/poolboy.erl#L222" rel="noreferrer">terminate handler</a>.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload