From ec77effc944ca99ceb017649c14e0428e9f08612 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Thu, 14 May 2020 19:35:12 +0200 Subject: [PATCH] Add option 'worker_shutdown' Allow changing the default of 5000ms for shutdown time of each single worker. --- README.md | 2 ++ src/wpool_process_sup.erl | 3 ++- test/wpool_SUITE.erl | 24 ++++++++++++++++++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 979fce1..7cbeeea 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,10 @@ To start a new worker pool, you can either use `wpool:start_pool` (if you want t * **worker_type**: The type of the worker. The available values are `gen_server`. The default value is `gen_server`. Eventually we'll add `gen_statem` as well. * **worker**: The [`gen_server`](http://erldocs.com/current/stdlib/gen_server.html) module that each worker will run and the `InitArgs` to use on the corresponding `start_link` call used to initiate it. The default value for this setting is `{wpool_worker, undefined}`. That means that if you don't provide a worker implementation, the pool will be generated with this default one. [`wpool_worker`](https://hexdocs.pm/worker_pool/wpool_worker.html) is a module that implements a very simple RPC-like interface. * **worker_opt**: Options that will be passed to each `gen_server` worker. This are the same as described at `gen_server` documentation. +* **worker_shutdown**: The `shutdown` option to be used in the child specs of the workers. Defaults to `5000`. * **strategy**: Not the worker selection strategy (discussed below) but the supervisor flags to be used in the supervisor over the individual workers (`wpool_process_sup`). Defaults to `{one_for_one, 5, 60}` * **pool_sup_intensity** and **pool_sup_period**: The intensity and period for the supervisor that manages the worker pool system (`wpool_pool`). The strategy of this supervisor must be `one_for_all` but the intensity and period may be changed from their defaults of `5` and `60`. +* **pool_sup_shutdown**: The `shutdown` option to be used for the supervisor that manages the worker pool system (`wpool_pool`). Defaults to `brutal_kill`. * **queue_type**: Order in which requests will be stored and handled by workers. This option can take values `lifo` or `fifo`. Defaults to `fifo`. * **enable_callbacks**: A boolean value determining if `event_manager` should be started for callback modules. Defaults to `false`. diff --git a/src/wpool_process_sup.erl b/src/wpool_process_sup.erl index 0486824..5bf5375 100644 --- a/src/wpool_process_sup.erl +++ b/src/wpool_process_sup.erl @@ -44,6 +44,7 @@ init({Name, Options}) -> %% We'll eventually add more types (like gen_statem), %% that's why this case remains end, + WorkerShutdown = proplists:get_value(worker_shutdown, Options, 5000), WorkerSpecs = [ { wpool_pool:worker_name(Name, I) , { WorkerType @@ -51,7 +52,7 @@ init({Name, Options}) -> , [wpool_pool:worker_name(Name, I), Worker, InitArgs, Options] } , permanent - , 5000 + , WorkerShutdown , worker , [Worker] } || I <- lists:seq(1, Workers)], diff --git a/test/wpool_SUITE.erl b/test/wpool_SUITE.erl index 2479325..4418781 100644 --- a/test/wpool_SUITE.erl +++ b/test/wpool_SUITE.erl @@ -25,6 +25,7 @@ -export([ stats/1 , stop_pool/1 , non_brutal_shutdown/1 + , brutal_worker_shutdown/1 , overrun/1 , kill_on_overrun/1 , too_much_overrun/1 @@ -39,8 +40,8 @@ -spec all() -> [atom()]. all() -> - [too_much_overrun, overrun, stop_pool, non_brutal_shutdown, stats, - default_strategy, default_options, complete_coverage, broadcast, + [too_much_overrun, overrun, stop_pool, non_brutal_shutdown, brutal_worker_shutdown, + stats, default_strategy, default_options, complete_coverage, broadcast, kill_on_overrun, worker_killed_stats]. -spec init_per_suite(config()) -> config(). @@ -235,6 +236,25 @@ non_brutal_shutdown(_Config) -> {comment, []}. +-spec brutal_worker_shutdown(config()) -> {comment, []}. +brutal_worker_shutdown(_Config) -> + {ok, PoolPid} = wpool:start_sup_pool(wpool_SUITE_non_brutal_shutdown, + [{workers, 1}, + {pool_sup_shutdown, 100}, + {worker_shutdown, brutal_kill}]), + true = erlang:is_process_alive(PoolPid), + Stats = wpool:stats(wpool_SUITE_non_brutal_shutdown), + {workers, [{WorkerId, _}]} = lists:keyfind(workers, 1, Stats), + Worker = wpool_pool:worker_name(wpool_SUITE_non_brutal_shutdown, WorkerId), + monitor(process, Worker), + ok = wpool:stop_sup_pool(wpool_SUITE_non_brutal_shutdown), + receive {'DOWN', _, process, {Worker, _}, Reason} -> killed = Reason + after 200 -> + ct:fail(worker_not_stopped) + end, + + {comment, []}. + -spec stats(config()) -> {comment, []}. stats(_Config) -> Get = fun proplists:get_value/2,