This is an automated email from the ASF dual-hosted git repository. iilyak pushed a commit to branch retry-on-noproc-errors-2 in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit f872aa56e915ce92bd7c0ec1e7f9e2638f126fa4 Author: ILYA Khlopotov <[email protected]> AuthorDate: Thu Sep 11 12:01:09 2025 -0700 Re-open index on exit:{noproc, _} in dreyfus --- src/dreyfus/src/dreyfus_index_manager.erl | 13 ++++++++++++- src/dreyfus/src/dreyfus_rpc.erl | 15 ++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/dreyfus/src/dreyfus_index_manager.erl b/src/dreyfus/src/dreyfus_index_manager.erl index 6b7649d1b..658f5a086 100644 --- a/src/dreyfus/src/dreyfus_index_manager.erl +++ b/src/dreyfus/src/dreyfus_index_manager.erl @@ -20,7 +20,7 @@ -define(BY_PID, dreyfus_by_pid). % public api. --export([start_link/0, get_index/2, get_disk_size/2]). +-export([start_link/0, get_index/2, reopen_index/2, get_disk_size/2]). % gen_server api. -export([ @@ -39,6 +39,9 @@ start_link() -> get_index(DbName, Index) -> gen_server:call(?MODULE, {get_index, DbName, Index}, infinity). +reopen_index(DbName, Index) -> + gen_server:call(?MODULE, {reopen, DbName, Index}, infinity). + get_disk_size(DbName, #index{sig = Sig}) -> Path = <<DbName/binary, "/", Sig/binary>>, clouseau_rpc:disk_size(Path). @@ -66,6 +69,14 @@ handle_call({get_index, DbName, #index{sig = Sig} = Index}, From, State) -> [{_, ExistingPid}] -> {reply, {ok, ExistingPid}, State} end; +handle_call({reopen, DbName, #index{sig = Sig} = Index}, From, State) -> + case ets:lookup(?BY_SIG, {DbName, Sig}) of + [{_, ExistingPid}] when is_pid(ExistingPid) -> + true = ets:delete(?BY_SIG, {DbName, Sig}); + _ -> + ok + end, + handle_call({get_index, DbName, Index}, From, State); handle_call({open_ok, DbName, Sig, NewPid}, {OpenerPid, _}, State) -> link(NewPid), [{_, WaitList}] = ets:lookup(?BY_SIG, {DbName, Sig}), diff --git a/src/dreyfus/src/dreyfus_rpc.erl b/src/dreyfus/src/dreyfus_rpc.erl index 11076a63e..69d31f63c 100644 --- a/src/dreyfus/src/dreyfus_rpc.erl +++ b/src/dreyfus/src/dreyfus_rpc.erl @@ -50,7 +50,20 @@ call(Fun, DbName, DDoc, IndexName, QueryArgs0) -> maybe {ok, Index} ?= dreyfus_index:design_doc_to_index(DDoc, IndexName), {ok, Pid} ?= dreyfus_index_manager:get_index(DbName, Index), - rexi:reply(index_call(Fun, Pid, MinSeq, QueryArgs)) + try + rexi:reply(index_call(Fun, Pid, MinSeq, QueryArgs)) + catch + exit:{noproc, _} -> + couch_log:error("Got NOPROC, re-trying", []), + %% try one more time to handle the case when Clouseau's LRU + %% closed the index in the middle of our call + case dreyfus_index_manager:reopen_index(DbName, Index) of + {ok, Pid} -> + rexi:reply(index_call(Fun, Pid, MinSeq, QueryArgs)); + ReopenError -> + rexi:reply(ReopenError) + end + end else Error -> rexi:reply(Error)
