diff --git a/src/poolboy.erl b/src/poolboy.erl index db4973b..d7a634e 100644 --- a/src/poolboy.erl +++ b/src/poolboy.erl @@ -5,7 +5,7 @@ -export([checkout/1, checkout/2, checkout/3, checkin/2, transaction/2, transaction/3, child_spec/2, child_spec/3, start/1, start/2, - start_link/1, start_link/2, stop/1, status/1]). + start_link/1, start_link/2, stop/1, status/1, estatus/1]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export_type([pool/0]). @@ -122,6 +122,10 @@ stop(Pool) -> status(Pool) -> gen_server:call(Pool, status). +-spec estatus(Pool :: pool()) -> {atom(), integer(), integer(), integer()}. +estatus(Pool) -> + gen_server:call(Pool, estatus). + init({PoolArgs, WorkerArgs}) -> process_flag(trap_exit, true), Waiting = queue:new(), @@ -206,6 +210,18 @@ handle_call(status, _From, State) -> overflow = Overflow} = State, StateName = state_name(State), {reply, {StateName, length(Workers), Overflow, ets:info(Monitors, size)}, State}; +handle_call(estatus, _From, State) -> + #state{workers = Workers, + monitors = Monitors, + overflow = Overflow, + waiting = Waiting} = State, + StateName = state_name(State), + Status = {StateName, + length(Workers), + Overflow, + ets:info(Monitors, size), + queue:len(Waiting)}, + {reply, Status, State}; handle_call(get_avail_workers, _From, State) -> Workers = State#state.workers, {reply, Workers, State}; diff --git a/test/poolboy_tests.erl b/test/poolboy_tests.erl index b0f3b39..cf5d3c5 100644 --- a/test/poolboy_tests.erl +++ b/test/poolboy_tests.erl @@ -50,6 +50,8 @@ pool_test_() -> }, {<<"Pool returns status">>, fun pool_returns_status/0 + },{<<"Pool returns extended status">>, + fun pool_returns_estatus/0 }, {<<"Pool demonitors previously waiting processes">>, fun demonitors_previously_waiting_processes/0 @@ -446,6 +448,38 @@ pool_returns_status() -> ?assertEqual({full, 0, 0, 0}, poolboy:status(Pool4)), ok = pool_call(Pool4, stop). +pool_returns_estatus() -> + {ok, Pool} = new_pool(2, 0), + ?assertEqual({ready, 2, 0, 0, 0}, poolboy:estatus(Pool)), + poolboy:checkout(Pool), + ?assertEqual({ready, 1, 0, 1, 0}, poolboy:estatus(Pool)), + poolboy:checkout(Pool), + ?assertEqual({full, 0, 0, 2, 0}, poolboy:estatus(Pool)), + spawn(fun() -> poolboy:checkout(Pool) end), + timer:sleep(50), + ?assertEqual({full, 0, 0, 2, 1}, poolboy:estatus(Pool)), + ok = pool_call(Pool, stop), + + {ok, Pool2} = new_pool(1, 1), + ?assertEqual({ready, 1, 0, 0, 0}, poolboy:estatus(Pool2)), + poolboy:checkout(Pool2), + ?assertEqual({overflow, 0, 0, 1, 0}, poolboy:estatus(Pool2)), + poolboy:checkout(Pool2), + ?assertEqual({full, 0, 1, 2, 0}, poolboy:estatus(Pool2)), + ok = pool_call(Pool2, stop), + + {ok, Pool3} = new_pool(0, 2), + ?assertEqual({overflow, 0, 0, 0, 0}, poolboy:estatus(Pool3)), + poolboy:checkout(Pool3), + ?assertEqual({overflow, 0, 1, 1, 0}, poolboy:estatus(Pool3)), + poolboy:checkout(Pool3), + ?assertEqual({full, 0, 2, 2, 0}, poolboy:estatus(Pool3)), + ok = pool_call(Pool3, stop), + + {ok, Pool4} = new_pool(0, 0), + ?assertEqual({full, 0, 0, 0, 0}, poolboy:estatus(Pool4)), + ok = pool_call(Pool4, stop). + demonitors_previously_waiting_processes() -> {ok, Pool} = new_pool(1,0), Self = self(),