From 6aa04d06ade041744bc0fefafb464dde075d4ee8 Mon Sep 17 00:00:00 2001 From: Nick Vatamaniuc Date: Sat, 16 Mar 2024 03:03:33 -0400 Subject: [PATCH] Fix case clause error in replicator _scheduler/docs response When a job is completing, there is a period of time when the document isn't updated yet with the state, and it's also not present in the scheduler ets table. In that case we return `nil`, but we don't account for that case in the _scheduler/docs fabric calls. To fix it, account for `nil` whenever we get the doc state. --- src/couch_replicator/src/couch_replicator_fabric.erl | 4 +++- src/couch_replicator/src/couch_replicator_fabric_rpc.erl | 5 ++++- .../test/eunit/couch_replicator_scheduler_docs_tests.erl | 5 +---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/couch_replicator/src/couch_replicator_fabric.erl b/src/couch_replicator/src/couch_replicator_fabric.erl index 9a069fac99c..d570d6f7728 100644 --- a/src/couch_replicator/src/couch_replicator_fabric.erl +++ b/src/couch_replicator/src/couch_replicator_fabric.erl @@ -18,7 +18,6 @@ -include_lib("fabric/include/fabric.hrl"). -include_lib("mem3/include/mem3.hrl"). --include_lib("couch/include/couch_db.hrl"). -include_lib("couch_mrview/include/couch_mrview.hrl"). docs(DbName, Options, QueryArgs, Callback, Acc) -> @@ -167,6 +166,9 @@ maybe_fetch_and_filter_doc(Id, undecided, State) -> {ok, {Props} = DocInfo} -> DocState = couch_util:get_value(state, Props), couch_replicator_utils:filter_state(DocState, FilterStates, DocInfo); + {ok, nil} -> + % could have just completed + skip; {error, not_found} -> % could have been deleted skip diff --git a/src/couch_replicator/src/couch_replicator_fabric_rpc.erl b/src/couch_replicator/src/couch_replicator_fabric_rpc.erl index f6b9b408099..1a3582928ee 100644 --- a/src/couch_replicator/src/couch_replicator_fabric_rpc.erl +++ b/src/couch_replicator/src/couch_replicator_fabric_rpc.erl @@ -17,7 +17,6 @@ ]). -include_lib("fabric/include/fabric.hrl"). --include_lib("couch/include/couch_db.hrl"). -include_lib("couch_mrview/include/couch_mrview.hrl"). docs(DbName, Options, Args0) -> @@ -80,6 +79,10 @@ rep_doc_state(Shard, Id, {[_ | _]} = Doc, States, HealthThreshold) -> HealthThreshold ) of + {ok, nil} -> + % Could have been just completed. Let the coordinator + % try to refetch it. + undecided; {ok, EtsInfo} -> State = get_doc_state(EtsInfo), couch_replicator_utils:filter_state(State, States, EtsInfo); diff --git a/src/couch_replicator/test/eunit/couch_replicator_scheduler_docs_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_scheduler_docs_tests.erl index e04518b6722..15789da692f 100644 --- a/src/couch_replicator/test/eunit/couch_replicator_scheduler_docs_tests.erl +++ b/src/couch_replicator/test/eunit/couch_replicator_scheduler_docs_tests.erl @@ -133,10 +133,7 @@ t_scheduler_docs_total_rows({_Ctx, {RepDb, Source, Target}}) -> case req(get, SchedulerDocsUrl) of {200, #{<<"docs">> := [_ | _]} = Decoded} -> Decoded; - {_, #{<<"error">> := Error, <<"reason">> := Reason}} -> - ?debugVal(Error, 100), - ?debugVal(binary_to_list(Reason), 100); - {_, #{}} -> + {200, #{<<"docs">> := []}} -> wait end end,