Use RealReplyCount to distinguish worker replies and invalid docs
We use {ok, []} in couch_db:open_doc_revs_int/3 as a return value
when the document does not exist and open_revs=all. This leads to an
incorrect all_workers_died error. We use ReplyCount and RealReplyCount
to distinguish between when no workers were actually used in a reply
versus when the document does not exist
COUCHDB-3113
diff --git a/src/fabric_doc_open_revs.erl b/src/fabric_doc_open_revs.erl
index 6c8912b..096722f 100644
--- a/src/fabric_doc_open_revs.erl
+++ b/src/fabric_doc_open_revs.erl
@@ -47,7 +47,7 @@
},
RexiMon = fabric_util:create_monitors(Workers),
try fabric_util:recv(Workers, #shard.ref, fun handle_message/3, State) of
- {ok, []} ->
+ {ok, all_workers_died} ->
{error, all_workers_died};
{ok, Replies} ->
{ok, Replies};
@@ -92,8 +92,9 @@
IsTree = Revs == all orelse Latest,
% Do not count error replies when checking quorum
- QuorumReplies = ReplyCount + 1 - ReplyErrorCount >= R,
+ RealReplyCount = ReplyCount + 1 - ReplyErrorCount,
+ QuorumReplies = RealReplyCount >= R,
{NewReplies, QuorumMet, Repair} = case IsTree of
true ->
{NewReplies0, AllInternal, Repair0} =
@@ -119,7 +120,7 @@
ReplyCount + 1,
InRepair orelse Repair
),
- {stop, format_reply(IsTree, NewReplies)};
+ {stop, format_reply(IsTree, NewReplies, RealReplyCount)};
false ->
{ok, State#state{
replies = NewReplies,
@@ -219,10 +220,13 @@
end.
-format_reply(true, Replies) ->
+format_reply(_, _, RealReplyCount) when RealReplyCount =< 0 ->
+ all_workers_died;
+
+format_reply(true, Replies, _) ->
tree_format_replies(Replies);
-format_reply(false, Replies) ->
+format_reply(false, Replies, _) ->
Filtered = filter_reply(Replies),
dict_format_replies(Filtered).
@@ -500,7 +504,7 @@
Msg1 = {rexi_EXIT, reason},
Msg2 = {rexi_EXIT, reason},
Msg3 = {rexi_DOWN, nodedown, {nil, node()}, nil},
- Expect = {stop, []},
+ Expect = {stop, all_workers_died},
{ok, S1} = handle_message(Msg1, w1, S0),
{ok, S2} = handle_message(Msg2, w2, S1),