This is an automated email from the ASF dual-hosted git repository.
chewbranca pushed a commit to branch couch-stats-resource-tracker-rebase
in repository https://gitbox.apache.org/repos/asf/couchdb.git
The following commit(s) were added to
refs/heads/couch-stats-resource-tracker-rebase by this push:
new f233789ed Delay PidRef eviction for unsafe folds
f233789ed is described below
commit f233789ed3e5f5db084567b6880a0e40cd9279df
Author: Russell Branca <[email protected]>
AuthorDate: Wed Mar 6 15:16:53 2024 -0800
Delay PidRef eviction for unsafe folds
---
.../src/couch_stats_resource_tracker.erl | 55 +++++++++++++++++++++-
1 file changed, 53 insertions(+), 2 deletions(-)
diff --git a/src/couch_stats/src/couch_stats_resource_tracker.erl
b/src/couch_stats/src/couch_stats_resource_tracker.erl
index ee7e79ed8..55f402e60 100644
--- a/src/couch_stats/src/couch_stats_resource_tracker.erl
+++ b/src/couch_stats/src/couch_stats_resource_tracker.erl
@@ -24,6 +24,12 @@
terminate/2
]).
+-export([
+ pause_eviction/0,
+ enable_eviction/0,
+ eviction_status/0
+]).
+
-export([
inc/1, inc/2,
maybe_inc/2,
@@ -135,6 +141,8 @@
-record(st, {
+ eviction = enabled, %% or paused
+ ev_queue = [], %% eviction queue for when eviction is paused
eviction_delay = 10 * 1000, %% How many ms dead processes are visible
scan_interval = 2048, %% How regularly to perfom scans
tracking = #{} %% track active processes for eventual eviction
@@ -456,7 +464,20 @@ group_by(KeyFun, ValFun, AggFun, Fold) ->
Acc
end
end,
- Fold(FoldFun, #{}, ?MODULE).
+ case conf_get("fold_fun") of
+ "unsafe" ->
+ %% When fold_fun is unsafe we must pause deletion of keys as
+ %% otherwise `ets:next/2` will fail when the supplied key has
+ %% already been deleted
+ pause_eviction(),
+ try
+ Fold(FoldFun, #{}, ?MODULE)
+ after
+ enable_eviction()
+ end;
+ _ ->
+ Fold(FoldFun, #{}, ?MODULE)
+ end.
%% Sorts largest first
@@ -871,6 +892,18 @@ find_by_pid(Pid) ->
[R || #rctx{} = R <- ets:match_object(?MODULE, #rctx{pid_ref={Pid, '_'}, _
= '_'})].
+pause_eviction() ->
+ gen_server:call(?MODULE, pause_eviction).
+
+
+enable_eviction() ->
+ gen_server:call(?MODULE, enable_eviction).
+
+
+eviction_status() ->
+ gen_server:call(?MODULE, enable_eviction).
+
+
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
@@ -892,6 +925,13 @@ init([]) ->
end,
{ok, St}.
+handle_call(eviction_status, _from, #st{eviction=Eviction, ev_queue=EVQ} = St)
->
+ {reply, {ok, Eviction, length(EVQ)}, St};
+handle_call(pause_eviction, _from, #st{eviction=Eviction} = St) ->
+ {reply, {ok, Eviction}, St#st{eviction=paused}};
+handle_call(enable_eviction, _from, #st{eviction=Eviction, ev_queue=EVQ} = St)
->
+ evict(EVQ),
+ {reply, {ok, Eviction}, St#st{eviction=enabled, ev_queue=[]}};
handle_call(fetch, _from, #st{} = St) ->
{reply, {ok, St}, St};
handle_call({track, _}=Msg, _From, St) ->
@@ -943,8 +983,10 @@ handle_info({'DOWN', MonRef, _Type, DPid, Reason0},
#st{tracking=AT0} = St0) ->
St0#st{tracking=AT}
end,
{noreply, St};
+handle_info({evict, {_Pid, _Ref}=PidRef}, #st{eviction=paused,
ev_queue=EVQ}=St) ->
+ {noreply, St#st{ev_queue=[PidRef|EVQ]}};
handle_info({evict, {_Pid, _Ref}=PidRef}, #st{}=St) ->
- ets:delete(?MODULE, PidRef),
+ evict(PidRef),
{noreply, St};
handle_info(Msg, St) ->
{stop, {unknown_info, Msg}, St}.
@@ -956,6 +998,15 @@ code_change(_OldVsn, St, _Extra) ->
{ok, St}.
+evict([]) ->
+ true;
+evict([PidRef|Rest]) ->
+ evict(PidRef),
+ evict(Rest);
+evict(PidRef) ->
+ ets:delete(?MODULE, PidRef).
+
+
maybe_track([], AT) ->
AT;
maybe_track(PidRef, AT) when is_tuple(PidRef) ->