Permalink
Browse files

Use a deadline from the calling process

Closes #21.
  • Loading branch information...
1 parent 91b68de commit 6008f22ae95c84d058d8aaa62a186cf298061615 @devinus committed Oct 10, 2013
Showing with 23 additions and 20 deletions.
  1. +1 −1 package.exs
  2. +1 −1 package.head.exs
  3. +21 −18 src/poolboy.erl
View
@@ -5,7 +5,7 @@ Expm.Package.new(
description: "A hunky Erlang worker pool factory",
homepage: "http://devintorr.es/poolboy",
version: version,
- keywords: ["Erlang", "library", "pool", "pools", "pooler"],
+ keywords: %w(Erlang library pool pools pooler),
maintainers: [[name: "Devin Torres", email: "devin@devintorr.es"],
[name: "Andrew Thompson", email: "andrew@hijacked.us"]],
repositories: [[github: "devinus/poolboy", tag: version]]
View
@@ -3,7 +3,7 @@ Expm.Package.new(
description: "A hunky Erlang worker pool factory",
homepage: "http://devinus.github.com/poolboy/",
version: :head,
- keywords: ["Erlang", "library", "pool", "pools", "pooler"],
+ keywords: %w(Erlang library pool pools pooler),
maintainers: [[name: "Devin Torres", email: "devin@devintorr.es"],
[name: "Andrew Thompson", email: "andrew@hijacked.us"]],
repositories: [[github: "devinus/poolboy"]]
View
@@ -31,8 +31,12 @@ checkout(Pool, Block) ->
-spec checkout(Pool :: node(), Block :: boolean(), Timeout :: timeout())
-> pid() | full.
+checkout(Pool, Block, infinity) ->
+ gen_server:call(Pool, {checkout, Block, infinity}, infinity);
checkout(Pool, Block, Timeout) ->
- gen_server:call(Pool, {checkout, Block, Timeout}, Timeout).
+ {MegaSecs, Secs, MicroSecs} = os:timestamp(),
+ Deadline = {MegaSecs, Secs, MicroSecs + Timeout},
+ gen_server:call(Pool, {checkout, Block, Deadline}, Timeout).
-spec checkin(Pool :: node(), Worker :: pid()) -> ok.
checkin(Pool, Worker) when is_pid(Worker) ->
@@ -130,7 +134,7 @@ handle_cast({checkin, Pid}, State = #state{monitors = Monitors}) ->
handle_cast(_Msg, State) ->
{noreply, State}.
-handle_call({checkout, Block, Timeout}, {FromPid, _} = From, State) ->
+handle_call({checkout, Block, Deadline}, {FromPid, _} = From, State) ->
#state{supervisor = Sup,
workers = Workers,
monitors = Monitors,
@@ -148,7 +152,7 @@ handle_call({checkout, Block, Timeout}, {FromPid, _} = From, State) ->
{empty, Empty} when Block =:= false ->
{reply, full, State#state{workers = Empty}};
{empty, Empty} ->
- Waiting = add_waiting(From, Timeout, State#state.waiting),
+ Waiting = add_waiting(From, Deadline, State#state.waiting),
{noreply, State#state{workers = Empty, waiting = Waiting}}
end;
@@ -252,29 +256,28 @@ prepopulate(0, _Sup, Workers) ->
prepopulate(N, Sup, Workers) ->
prepopulate(N-1, Sup, queue:in(new_worker(Sup), Workers)).
-add_waiting(Pid, Timeout, Queue) ->
- queue:in({Pid, Timeout, os:timestamp()}, Queue).
+add_waiting(Pid, Deadline, Queue) ->
+ queue:in({Pid, Deadline}, Queue).
-wait_valid(_StartTime, infinity) ->
- true;
-wait_valid(StartTime, Timeout) ->
- Waited = timer:now_diff(os:timestamp(), StartTime),
- (Waited div 1000) < Timeout.
+past_deadline(infinity) ->
+ false;
+past_deadline(Deadline) ->
+ timer:now_diff(os:timestamp(), Deadline) < 0.
handle_checkin(Pid, State) ->
#state{supervisor = Sup,
waiting = Waiting,
monitors = Monitors,
overflow = Overflow} = State,
case queue:out(Waiting) of
- {{value, {{FromPid, _} = From, Timeout, StartTime}}, Left} ->
- case wait_valid(StartTime, Timeout) of
- true ->
+ {{value, {{FromPid, _} = From, Deadline}}, Left} ->
+ case past_deadline(Deadline) of
+ false ->
Ref1 = erlang:monitor(process, FromPid),
true = ets:insert(Monitors, {Pid, Ref1}),
gen_server:reply(From, Pid),
State#state{waiting = Left};
- false ->
+ true ->
handle_checkin(Pid, State#state{waiting = Left})
end;
{empty, Empty} when Overflow > 0 ->
@@ -290,15 +293,15 @@ handle_worker_exit(Pid, State) ->
monitors = Monitors,
overflow = Overflow} = State,
case queue:out(State#state.waiting) of
- {{value, {{FromPid, _} = From, Timeout, StartTime}}, LeftWaiting} ->
- case wait_valid(StartTime, Timeout) of
- true ->
+ {{value, {{FromPid, _} = From, Deadline}}, LeftWaiting} ->
+ case past_deadline(Deadline) of
+ false ->
MonitorRef = erlang:monitor(process, FromPid),
NewWorker = new_worker(State#state.supervisor),
true = ets:insert(Monitors, {NewWorker, MonitorRef}),
gen_server:reply(From, NewWorker),
State#state{waiting = LeftWaiting};
- _ ->
+ true ->
handle_worker_exit(Pid, State#state{waiting = LeftWaiting})
end;
{empty, Empty} when Overflow > 0 ->

0 comments on commit 6008f22

Please sign in to comment.