You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2014/08/05 00:18:20 UTC
[18/20] couch commit: updated refs/heads/windsor-merge-102 to 944c542
Allow operator to forcibly terminate stale procs
This patch adds a new terminate_stale_procs/0 command which kills off
any OS processes with spawn times older than the current threshold time,
regardless of whether the process has a client. It also refactors the
internals to use the same logic to terminate a process in every case.
BugzID: 19529
Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/0e78ae2f
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/0e78ae2f
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/0e78ae2f
Branch: refs/heads/windsor-merge-102
Commit: 0e78ae2ff7a28cea5353dae05dc1432f1dfbe4fa
Parents: 814eadc
Author: Adam Kocoloski <ad...@cloudant.com>
Authored: Mon Jun 3 13:24:02 2013 -0400
Committer: Robert Newson <rn...@apache.org>
Committed: Mon Aug 4 18:39:47 2014 +0100
----------------------------------------------------------------------
src/couch_proc_manager.erl | 37 ++++++++++++++++++++++++-------------
1 file changed, 24 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/0e78ae2f/src/couch_proc_manager.erl
----------------------------------------------------------------------
diff --git a/src/couch_proc_manager.erl b/src/couch_proc_manager.erl
index e0f03e5..93c53cb 100644
--- a/src/couch_proc_manager.erl
+++ b/src/couch_proc_manager.erl
@@ -22,7 +22,8 @@
get_proc_count/0,
get_stale_proc_count/0,
new_proc/1,
- reload/0
+ reload/0,
+ terminate_stale_procs/0
]).
% config_listener api
@@ -69,6 +70,9 @@ get_stale_proc_count() ->
reload() ->
gen_server:call(?MODULE, bump_threshold_ts).
+terminate_stale_procs() ->
+ gen_server:call(?MODULE, terminate_stale_procs).
+
init([]) ->
process_flag(trap_exit, true),
ok = config:listen_for_changes(?MODULE, nil),
@@ -134,14 +138,20 @@ handle_call({ret_proc, #proc{client=Ref, lang=Lang0} = Proc}, _From, State) ->
handle_call(bump_threshold_ts, _From, #state{tab = Tab} = State) ->
FoldFun = fun(#proc_int{client = nil, pid = Pid}, _) ->
- gen_server:cast(Pid, stop),
- ets:delete(Tab, Pid);
+ remove_proc(Tab, Pid);
(_, _) ->
ok
end,
ets:foldl(FoldFun, nil, Tab),
{reply, ok, State#state{threshold_ts = os:timestamp()}};
+handle_call(terminate_stale_procs, _From, State) ->
+ #state{tab = Tab, threshold_ts = T0} = State,
+ MatchHead = #proc_int{pid = '$1', t0 = '$2', _ = '_'},
+ MatchSpec = [{MatchHead, [{'<', '$2', T0}], ['$1']}],
+ lists:foreach(fun(P) -> remove_proc(Tab,P) end, ets:select(Tab, MatchSpec)),
+ {reply, ok, State};
+
handle_call(_Call, _From, State) ->
{reply, ignored, State}.
@@ -153,14 +163,7 @@ handle_cast({os_proc_idle, Pid}, #state{tab=Tab, proc_counts=Counts}=State0) ->
case dict:find(Lang, Counts) of
{ok, Count} when Count > Limit ->
?LOG_INFO("Closing idle OS Process: ~p", [Pid]),
- ets:delete(Tab, Pid),
- case is_process_alive(Pid) of
- true ->
- unlink(Pid),
- gen_server:cast(Pid, stop);
- _ ->
- ok
- end,
+ remove_proc(Tab, Pid),
State0#state{
proc_counts=dict:update_counter(Lang, -1, Counts)
};
@@ -323,6 +326,15 @@ export_proc(#proc_int{} = ProcInt) ->
[_ | Data] = lists:sublist(record_info(size, proc), tuple_to_list(ProcInt)),
list_to_tuple([proc | Data]).
+remove_proc(Tab, Pid) ->
+ ets:delete(Tab, Pid),
+ case is_process_alive(Pid) of true ->
+ unlink(Pid),
+ gen_server:cast(Pid, stop);
+ false ->
+ ok
+ end.
+
proc_with_ddoc(DDoc, DDocKey, Procs) ->
Filter = fun(#proc_int{ddoc_keys=Keys}) -> not lists:member(DDocKey, Keys) end,
case lists:dropwhile(Filter, Procs) of
@@ -382,8 +394,7 @@ return_proc(State, #proc{pid=Pid, lang=Lang} = Proc) ->
nil ->
[ProcInt] = ets:lookup(Tab, Pid),
if ProcInt#proc_int.t0 < T0 ->
- gen_server:cast(Pid, stop),
- ets:delete(Tab, Pid);
+ remove_proc(Tab, Pid);
true ->
gen_server:cast(Pid, garbage_collect),
ets:insert(Tab, Proc#proc{client=nil})