Skip to content

Commit b4c345f

Browse files
author
juhlig
committed
lazy worker start
1 parent 9212a87 commit b4c345f

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

src/poolboy.erl

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@
4444
size = 5 :: non_neg_integer(),
4545
overflow = 0 :: non_neg_integer(),
4646
max_overflow = 10 :: non_neg_integer(),
47-
strategy = lifo :: lifo | fifo
47+
strategy = lifo :: lifo | fifo,
48+
lazy = false :: boolean()
4849
}).
4950

5051
-spec checkout(Pool :: pool()) -> pid().
@@ -162,8 +163,13 @@ init([{strategy, lifo} | Rest], WorkerArgs, State) ->
162163
init(Rest, WorkerArgs, State#state{strategy = lifo});
163164
init([{strategy, fifo} | Rest], WorkerArgs, State) ->
164165
init(Rest, WorkerArgs, State#state{strategy = fifo});
166+
init([{lazy, true} | Rest], WorkerArgs, State) ->
167+
init(Rest, WorkerArgs, State#state{lazy = true});
165168
init([_ | Rest], WorkerArgs, State) ->
166169
init(Rest, WorkerArgs, State);
170+
init([], _WorkerArgs, #state{lazy = true, size = Size} = State) ->
171+
Workers = prepopulate_empty(Size),
172+
{ok, State#state{workers = Workers}};
167173
init([], _WorkerArgs, #state{size = Size, supervisor = Sup} = State) ->
168174
Workers = prepopulate(Size, Sup),
169175
{ok, State#state{workers = Workers}}.
@@ -208,6 +214,10 @@ handle_call({checkout, CRef, Block}, {FromPid, _} = From, State) ->
208214
max_overflow = MaxOverflow,
209215
strategy = Strategy} = State,
210216
case get_worker_with_strategy(Workers, Strategy) of
217+
{{value, undefined}, Left} ->
218+
{Pid, MRef} = new_worker(Sup, FromPid),
219+
true = ets:insert(Monitors, {Pid, CRef, MRef}),
220+
{reply, Pid, State#state{workers = Left}};
211221
{{value, Pid}, Left} ->
212222
MRef = erlang:monitor(process, FromPid),
213223
true = ets:insert(Monitors, {Pid, CRef, MRef}),
@@ -268,6 +278,9 @@ handle_info({'EXIT', Pid, _Reason}, State) ->
268278
{noreply, NewState};
269279
[] ->
270280
case queue:member(Pid, State#state.workers) of
281+
true when State#state.lazy =:= true ->
282+
W = filter_worker_by_pid(Pid, State#state.workers),
283+
{noreply, State#state{workers = queue:in(undefined, W)}};
271284
true ->
272285
W = filter_worker_by_pid(Pid, State#state.workers),
273286
{noreply, State#state{workers = queue:in(new_worker(Sup), W)}};
@@ -328,6 +341,11 @@ prepopulate(0, _Sup, Workers) ->
328341
prepopulate(N, Sup, Workers) ->
329342
prepopulate(N-1, Sup, queue:in(new_worker(Sup), Workers)).
330343

344+
prepopulate_empty(N) when N < 1 ->
345+
queue:new();
346+
prepopulate_empty(N) ->
347+
queue:from_list([undefined || _ <- lists:seq(1, N)]).
348+
331349
handle_checkin(Pid, State) ->
332350
#state{supervisor = Sup,
333351
waiting = Waiting,
@@ -358,6 +376,10 @@ handle_worker_exit(Pid, State) ->
358376
State#state{waiting = LeftWaiting};
359377
{empty, Empty} when Overflow > 0 ->
360378
State#state{overflow = Overflow - 1, waiting = Empty};
379+
{empty, Empty} when State#state.lazy =:= true ->
380+
W = filter_worker_by_pid(Pid, State#state.workers),
381+
Workers = queue:in(undefined, W),
382+
State#state{workers = Workers, waiting = Empty};
361383
{empty, Empty} ->
362384
W = filter_worker_by_pid(Pid, State#state.workers),
363385
Workers = queue:in(new_worker(Sup), W),

0 commit comments

Comments
 (0)