This is an automated email from the ASF dual-hosted git repository.

tonysun83 pushed a commit to branch fix-reorder-util
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 415223287890ac3f6d6f2b8c80ad70b23aa291ca
Author: Tony Sun <[email protected]>
AuthorDate: Tue Mar 29 05:35:01 2022 -0700

    use undefined for timed out responses
    
    Under heavy load, fabric_update_doc workers will return timeout via
    rexi. Therefore no reponses will be populate the response dictionary.
    This leads to badargs when we do dict:fetch for keys that do not exist.
    This checks for the existence of the key and then returns undefined
    if it does not exist, which aligns with the same code path of when we
    the number of docs < 100.
---
 src/fabric/src/fabric_doc_update.erl | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/fabric/src/fabric_doc_update.erl 
b/src/fabric/src/fabric_doc_update.erl
index 1360bda..b0cf333 100644
--- a/src/fabric/src/fabric_doc_update.erl
+++ b/src/fabric/src/fabric_doc_update.erl
@@ -42,7 +42,7 @@ go(DbName, AllDocs0, Opts) ->
         {ok, {Health, Results}} when
             Health =:= ok; Health =:= accepted; Health =:= error
         ->
-            {Health, [R || R <- couch_util:reorder_results(AllDocs, Results), 
R =/= noreply]};
+            {Health, [R || R <- reorder_results(AllDocs, Results), R =/= 
noreply]};
         {timeout, Acc} ->
             {_, _, W1, GroupedDocs1, DocReplDict} = Acc,
             {DefunctWorkers, _} = lists:unzip(GroupedDocs1),
@@ -52,7 +52,7 @@ go(DbName, AllDocs0, Opts) ->
                 {ok, W1, []},
                 DocReplDict
             ),
-            {Health, [R || R <- couch_util:reorder_results(AllDocs, Resp), R 
=/= noreply]};
+            {Health, [R || R <- reorder_results(AllDocs, Resp), R =/= 
noreply]};
         Else ->
             Else
     after
@@ -193,6 +193,18 @@ maybe_reply(Doc, Replies, {stop, W, Acc}) ->
             continue
     end.
 
+reorder_results(AllDocs, Resp) when length(AllDocs) < 100 ->
+    couch_util:reorder_results(AllDocs, Resp);
+reorder_results(AllDocs, Resp) ->
+    KeyDict = dict:from_list(Resp),
+    Default = fun ({Key, Dict}) ->
+        case dict:is_key(Key, Dict) of
+            true -> dict:fetch(Key, Dict);
+            false -> undefined
+        end
+    end,
+    [Default({Key, KeyDict}) || Key <- AllDocs].
+
 % This is a corner case where
 % 1) revision tree for the document are out of sync across nodes
 % 2) update on one node extends the revision tree

Reply via email to