summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Sackman <matthew@rabbitmq.com>2010-08-16 16:49:00 +0100
committerMatthew Sackman <matthew@rabbitmq.com>2010-08-16 16:49:00 +0100
commita171cbbc2f1a2a7f3da9ca19410459a04ba0c38c (patch)
tree1ead8e71289169b5796aff3b86039c32f82905b8
parent1ebd2e52a0d15f94b1105abe866026d916ba72d9 (diff)
downloadrabbitmq-server-a171cbbc2f1a2a7f3da9ca19410459a04ba0c38c.tar.gz
Finally, it works. Important points: 1) remove elders from blocked clients so that we calculate average based on pids that can actually respond. 2) reduce whenever we have pending_opens to ensure we rotate the strike.
-rw-r--r--src/file_handle_cache.erl42
1 files changed, 24 insertions, 18 deletions
diff --git a/src/file_handle_cache.erl b/src/file_handle_cache.erl
index 1f5fe7b1..564ab35b 100644
--- a/src/file_handle_cache.erl
+++ b/src/file_handle_cache.erl
@@ -452,7 +452,7 @@ release_on_death(Pid) when is_pid(Pid) ->
gen_server:cast(?SERVER, {release_on_death, Pid}).
obtain() ->
- gen_server:call(?SERVER, obtain, infinity).
+ gen_server:call(?SERVER, {obtain, self()}, infinity).
%%----------------------------------------------------------------------------
%% Internal functions
@@ -740,21 +740,23 @@ init([]) ->
callbacks = dict:new(), client_mrefs = dict:new(),
timer_ref = undefined }}.
-handle_call(obtain, From, State = #fhc_state { obtains_count = Count,
- obtains_limit = Limit,
- obtains_pending = Pending })
+handle_call({obtain, Pid}, From, State =
+ #fhc_state { elders = Elders, obtains_count = Count,
+ obtains_limit = Limit, obtains_pending = Pending })
when Count >= Limit ->
- {noreply, State #fhc_state { obtains_pending = [From | Pending] }};
-handle_call(obtain, From, State = #fhc_state { obtains_count = ObtainsCount,
- obtains_pending = Pending,
- limit = Limit }) ->
+ {noreply, State #fhc_state { obtains_pending = [From | Pending],
+ elders = dict:erase(Pid, Elders) }};
+handle_call({obtain, Pid}, From, State =
+ #fhc_state { elders = Elders, obtains_count = ObtainsCount,
+ obtains_pending = Pending, limit = Limit }) ->
State1 = #fhc_state { opens_count = OpensCount1,
obtains_count = ObtainsCount1 } =
maybe_reduce(State #fhc_state { obtains_count = ObtainsCount + 1 }),
- case Limit =/= infinity andalso OpensCount1 + ObtainsCount1 >= Limit of
+ case Limit =/= infinity andalso OpensCount1 + ObtainsCount1 > Limit of
true ->
{noreply, State1 #fhc_state { obtains_count = ObtainsCount1 - 1,
- obtains_pending = [From | Pending] }};
+ obtains_pending = [From | Pending],
+ elders = dict:erase(Pid, Elders) }};
false ->
{reply, ok, State1}
end;
@@ -765,15 +767,17 @@ handle_call({open, Pid, EldestUnusedSince, CanClose}, From, State =
Elders1 = dict:store(Pid, EldestUnusedSince, Elders),
State1 = #fhc_state { opens_count = OpensCount1,
obtains_count = ObtainsCount1 } =
- maybe_reduce(State #fhc_state { opens_count = OpensCount + 1,
- elders = Elders1 }),
- case Limit =/= infinity andalso OpensCount1 + ObtainsCount1 >= Limit of
+ maybe_reduce(
+ ensure_mref(Pid, State #fhc_state { opens_count = OpensCount + 1,
+ elders = Elders1 })),
+ case Limit =/= infinity andalso OpensCount1 + ObtainsCount1 > Limit of
true ->
State2 = State1 #fhc_state { opens_count = OpensCount1 - 1 },
case CanClose of
true -> {reply, close, State2};
- false -> {noreply, State2 #fhc_state { opens_pending =
- [From | Pending] }}
+ false -> {noreply,
+ State2 #fhc_state { opens_pending = [From | Pending],
+ elders = Elders }}
end;
false ->
{reply, ok, State1}
@@ -868,19 +872,21 @@ process_pending(Pending, Quota) ->
{PendingNew, SatisfiableLen}.
maybe_reduce(State = #fhc_state { limit = Limit, opens_count = OpensCount,
+ opens_pending = OpensPending,
obtains_count = ObtainsCount,
obtains_limit = ObtainsLimit,
obtains_pending = ObtainsPending,
elders = Elders, callbacks = Callbacks,
timer_ref = TRef })
- when Limit /= infinity andalso
- (((OpensCount + ObtainsCount) >= Limit) orelse
+ when Limit =/= infinity andalso
+ (((OpensCount + ObtainsCount) > Limit) orelse
+ ([] =/= OpensPending) orelse
(ObtainsCount < ObtainsLimit andalso [] =/= ObtainsPending)) ->
Now = now(),
{Pids, Sum, ClientCount} =
dict:fold(fun (_Pid, undefined, Accs) ->
Accs;
- (Pid, Eldest, {PidsAcc, SumAcc, CountAcc}) ->
+ (Pid, Eldest, {PidsAcc, SumAcc, CountAcc} = Accs) ->
{[Pid|PidsAcc], SumAcc + timer:now_diff(Now, Eldest),
CountAcc + 1}
end, {[], 0, 0}, Elders),