summaryrefslogtreecommitdiff
path: root/apps/fabric
diff options
context:
space:
mode:
authorAdam Kocoloski <adam@cloudant.com>2010-10-19 16:06:02 -0400
committerAdam Kocoloski <adam@cloudant.com>2010-10-19 16:25:06 -0400
commitc9278ae9920fdc4373e8a5b2c174421bb2cc09a3 (patch)
tree02e1fdafc324d2d78627ca573d2687d63b2c7a4f /apps/fabric
parent025d358f116a4d29f072854aeb63488b1cd5569a (diff)
fix quorum check and be sure repair runs when revs are missing w/ open_revs=all
Diffstat (limited to 'apps/fabric')
-rw-r--r--apps/fabric/src/fabric_doc_open_revs.erl16
1 files changed, 14 insertions, 2 deletions
diff --git a/apps/fabric/src/fabric_doc_open_revs.erl b/apps/fabric/src/fabric_doc_open_revs.erl
index 03a9778d..70b88722 100644
--- a/apps/fabric/src/fabric_doc_open_revs.erl
+++ b/apps/fabric/src/fabric_doc_open_revs.erl
@@ -66,8 +66,11 @@ handle_message({ok, RawReplies}, _Worker, #state{revs = all} = State) ->
All0, RawReplies),
Reduced = remove_ancestors(All, []),
Complete = (ReplyCount =:= (WorkerCount - 1)),
- Repair = case Reduced of All -> false; _ ->
- [D || {{ok,D}, _} <- Reduced]
+ QuorumMet = lists:all(fun({_, C}) -> C >= R end, Reduced),
+ case Reduced of All when QuorumMet andalso ReplyCount =:= (R-1) ->
+ Repair = false;
+ _ ->
+ Repair = [D || {{ok,D}, _} <- Reduced]
end,
case maybe_reply(DbName, Reduced, Complete, Repair, R) of
noreply ->
@@ -113,6 +116,8 @@ skip(#state{revs=all} = State) ->
skip(#state{revs=Revs} = State) ->
handle_message({ok, [error || _Rev <- Revs]}, nil, State).
+maybe_reply(_, [], false, _, _) ->
+ noreply;
maybe_reply(DbName, ReplyDict, IsComplete, RepairDocs, R) ->
case lists:all(fun({_, C}) -> C >= R end, ReplyDict) of
true ->
@@ -223,6 +228,13 @@ all_revs_test() ->
Foo1 = {ok, #doc{revs = {1, [<<"foo">>]}}},
Foo2 = {ok, #doc{revs = {2, [<<"foo2">>, <<"foo">>]}}},
Bar1 = {ok, #doc{revs = {1, [<<"bar">>]}}},
+
+ % an empty worker response does not count as meeting quorum
+ ?assertMatch(
+ {ok, #state{}},
+ handle_message({ok, []}, nil, State0)
+ ),
+
?assertMatch(
{ok, #state{}},
handle_message({ok, [Foo1, Bar1]}, nil, State0)