diff options
author | Matthew Sackman <matthew@rabbitmq.com> | 2010-08-16 16:49:00 +0100 |
---|---|---|
committer | Matthew Sackman <matthew@rabbitmq.com> | 2010-08-16 16:49:00 +0100 |
commit | a171cbbc2f1a2a7f3da9ca19410459a04ba0c38c (patch) | |
tree | 1ead8e71289169b5796aff3b86039c32f82905b8 | |
parent | 1ebd2e52a0d15f94b1105abe866026d916ba72d9 (diff) | |
download | rabbitmq-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.erl | 42 |
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), |