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)

Reply via email to