Strange error message when stopping application using lager and poolboy

I created a simple application using a pulboy with an almost empty worker, but when I stop the application, I see the following error printed by lager:

10:50:26.363 [error] Supervisor {<0.236.0>,poolboy_sup} had child test_worker started with test_worker:start_link([]) at undefined exit with reason shutdown in context shutdown_error 

What causes this error and how can I fix it?

Head:

 -module(test_sup). -behaviour(supervisor). -export([start_link/0, init/1]). start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> ChildSpecs = [pool_spec()], {ok, {{one_for_one, 1000, 3600}, ChildSpecs}}. pool_spec() -> Name = test_pool, PoolArgs = [{name, {local, Name}}, {worker_module, test_worker}, {size, 10}, {max_overflow, 20}], poolboy:child_spec(Name, PoolArgs, []). 

Working:

 -module(test_worker). -behaviour(gen_server). -behaviour(poolboy_worker). -export([start_link/1]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -record(state, {}). start_link([]) -> gen_server:start_link(?MODULE, [], []). init([]) -> {ok, #state{}}. handle_call(_Request, _From, State) -> {reply, _Reply = ok, State}. handle_cast(_Msg, State) -> {noreply, State}. handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. 

The rest of the application is pretty standard.

Erlang: R16B02

Poolboy: 1.0.1

Lager: latest version from the wizard at the time of writing the question (822062478a223313dce30e5a45e30a50a4b7dc4e)

+6
source share
2 answers

The error you see is not really an error, but the error report generated by lager . This report is apparently caused by a bullet bug .

You can:

  • Fix the bug and send the patch to the poolboy developers.
  • Safe ignoring the report.
  • Manually complete your work when exiting.

What should happen when the OTP application stops is that the control tree is used to terminate all processes, preferably gracefully. The default method is to send controlled processes to the shutdown signal, and if this does not work after a while, it is brutal to kill them. You never get any report when everything goes smoothly.

To understand the error, there are two subtleties of Erlang:

  • Processes can be connected , which means that when one process aborts abnormally (that is, for a reason other than normal ), all related processes terminate for the same reason. This primitive is the basis of OTP observation.
  • A process can track output signals (or trap outputs), which means that it accepts output signals as normal messages instead of being terminated (including normal , which would not terminate it, but excluding kill , which unconditionally terminates it).

Connections combined with capture outputs are often used to control the completion of processes, with the added benefit of terminating controlled processes when the monitoring process ends. For example, if the supervisor ends, his children should be discontinued. There is also an asymmetric monitor mechanism.

Here, your supervisor (implementing the test_sup behavior) ends with the reason shutdown , as it should be. The behavior of the supervisor is actually an output trap, and when he receives a shutdown signal, he tries to complete his children in accordance with his shutdown strategy. Here you use the default strategy, which is to send the children a shutdown signal as a first attempt. Therefore, your supervisor sends a shutdown signal to his only child.

Poolboy introduces his magic here, and your supervisor's child is actually a gen_server with a poolboy callback module. He must close the pool and stop the grace.

This module is associated with the pool manager , but also with workers . This unexpected choice of implementation is likely that a pool crash (pool gen_server ) will stop working. However, this is the source of the error, and an asymmetric monitor is likely to make more sense. Since the supervisor is already associated with the gen_server gen_server , terminating the poolboy process will ultimately lead to the termination of workers.

The consequence of the workers reference is that they also receive the shutdown exit signal, which was originally directed to the poolboy process. And they are discontinued. This termination is considered an abnormal worker leader (executing a poolboy_sup ) because it does not send the signal itself. As a result, the dispatcher reports a shutdown that is logged here by lager.

The fact that poolboy traps terminate does not prevent the shutdown signal from propagating. A process is not interrupted immediately when it receives a signal, but receives it as a message. gen_server intercepts this message, calls the terminate/2 callback function, and then exits with shutdown , eventually propagating the signal to all related processes.

If you avoid referencing workers , this is not an option; a way to fix this error would be to disable all workers in the complete handler .

+5
source

How to stop the application? Perhaps the manager should have a stop / 1 function? e.g. see

http://www.erlang.org/doc/apps/kernel/application.html#stop-1

0
source

Source: https://habr.com/ru/post/955894/


All Articles