Skip to content

Commit

Permalink
Reuse the waiting monitor when a worker exits
Browse files Browse the repository at this point in the history
Fixes #61.
  • Loading branch information
Devin Torres committed Dec 3, 2014
1 parent 52d87c2 commit 94a3f7a
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
5 changes: 2 additions & 3 deletions src/poolboy.erl
Expand Up @@ -307,10 +307,9 @@ handle_worker_exit(Pid, State) ->
monitors = Monitors,
overflow = Overflow} = State,
case queue:out(State#state.waiting) of
{{value, {{FromPid, _} = From, _}}, LeftWaiting} ->
MonitorRef = erlang:monitor(process, FromPid),
{{value, {From, Ref}}, LeftWaiting} ->
NewWorker = new_worker(State#state.supervisor),
true = ets:insert(Monitors, {NewWorker, MonitorRef}),
true = ets:insert(Monitors, {NewWorker, Ref}),
gen_server:reply(From, NewWorker),
State#state{waiting = LeftWaiting};
{empty, Empty} when Overflow > 0 ->
Expand Down
22 changes: 22 additions & 0 deletions test/poolboy_tests.erl
Expand Up @@ -65,6 +65,9 @@ pool_test_() ->
},
{<<"Check FIFO strategy">>,
fun fifo_strategy/0
},
{<<"Pool reuses waiting monitor when a worker exits">>,
fun reuses_waiting_monitor_on_worker_exit/0
}
]
}.
Expand Down Expand Up @@ -465,6 +468,25 @@ fifo_strategy() ->
Worker1 = poolboy:checkout(Pid),
poolboy:stop(Pid).

reuses_waiting_monitor_on_worker_exit() ->
{ok, Pool} = new_pool(1,0),

Self = self(),
Pid = spawn(fun() ->
Worker = poolboy:checkout(Pool),
Self ! {worker, Worker},
poolboy:checkout(Pool),
receive ok -> ok end
end),

Worker = receive {worker, Worker} -> Worker end,
exit(Worker, kill),

?assertEqual(1, length(get_monitors(Pool))),

Pid ! ok,
ok = pool_call(Pool, stop).

get_monitors(Pid) ->
[{monitors, Monitors}] = erlang:process_info(Pid, [monitors]),
Monitors.
Expand Down

0 comments on commit 94a3f7a

Please sign in to comment.