This is an automated email from the ASF dual-hosted git repository.
vatamane pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/couchdb.git
The following commit(s) were added to refs/heads/master by this push:
new 52ed7fb Ignore local nodes in read repair filtering
52ed7fb is described below
commit 52ed7fbf48b953c3cd0dd5c058186a6af01dbc64
Author: Nick Vatamaniuc <[email protected]>
AuthorDate: Wed Sep 19 15:56:55 2018 -0400
Ignore local nodes in read repair filtering
Previosly local node revisions were causing `badmatch` failures in read
repair
filter. Node sequences already filtered out local nodes while NodeRevs
didn't, so
during matching `{Node, NodeSeq} = lists:keyfind(Node, 1, NodeSeqs)` Node
would
not be found in the list and crash.
Example of crash:
```
fabric_rpc:update_docs/3 error:{badmatch,false}
[{fabric_rpc,'-read_repair_filter/3-fun-1-',4,[{file,"src/fabric_rpc.erl"},{line,360}]},
```
---
src/fabric/src/fabric_rpc.erl | 5 +++--
src/fabric/test/fabric_rpc_purge_tests.erl | 24 +++++++++++++++++++++++-
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/src/fabric/src/fabric_rpc.erl b/src/fabric/src/fabric_rpc.erl
index c684229..11e6754 100644
--- a/src/fabric/src/fabric_rpc.erl
+++ b/src/fabric/src/fabric_rpc.erl
@@ -347,7 +347,8 @@ read_repair_filter(DbName, Docs, NodeRevs, Options) ->
% as the read_repair option to update_docs.
read_repair_filter(Db, Docs, NodeRevs) ->
[#doc{id = DocId} | _] = Docs,
- Nodes = lists:usort([Node || {Node, _} <- NodeRevs, Node /= node()]),
+ NonLocalNodeRevs = [NR || {N, _} = NR <- NodeRevs, N /= node()],
+ Nodes = lists:usort([Node || {Node, _} <- NonLocalNodeRevs]),
NodeSeqs = get_node_seqs(Db, Nodes),
DbPSeq = couch_db:get_purge_seq(Db),
@@ -360,7 +361,7 @@ read_repair_filter(Db, Docs, NodeRevs) ->
{Node, NodeSeq} = lists:keyfind(Node, 1, NodeSeqs),
NodeSeq >= DbPSeq - Lag
end,
- RecentNodeRevs = lists:filter(NodeFiltFun, NodeRevs),
+ RecentNodeRevs = lists:filter(NodeFiltFun, NonLocalNodeRevs),
% For each node we scan the purge infos to filter out any
% revisions that have been locally purged since we last
diff --git a/src/fabric/test/fabric_rpc_purge_tests.erl
b/src/fabric/test/fabric_rpc_purge_tests.erl
index 26507cf..4eafb2b 100644
--- a/src/fabric/test/fabric_rpc_purge_tests.erl
+++ b/src/fabric/test/fabric_rpc_purge_tests.erl
@@ -46,6 +46,7 @@ main_test_() ->
lists:map(fun wrap/1, [
?TDEF(t_filter),
?TDEF(t_filter_unknown_node),
+ ?TDEF(t_filter_local_node),
?TDEF(t_no_filter_old_node),
?TDEF(t_no_filter_different_node),
?TDEF(t_no_filter_after_repl)
@@ -58,6 +59,7 @@ main_test_() ->
lists:map(fun wrap/1, [
?TDEF(t_filter),
?TDEF(t_filter_unknown_node),
+ ?TDEF(t_filter_local_node),
?TDEF(t_no_filter_old_node),
?TDEF(t_no_filter_different_node),
?TDEF(t_no_filter_after_repl)
@@ -172,6 +174,26 @@ t_no_filter_different_node({DbName, DocId, OldDoc, PSeq})
->
?assertEqual({ok, OldDoc}, open_doc(DbName, DocId)).
+t_filter_local_node({DbName, DocId, OldDoc, PSeq}) ->
+ ?assertEqual({not_found, missing}, open_doc(DbName, DocId)),
+ create_purge_checkpoint(DbName, PSeq),
+
+ % Create a valid purge for a different node
+ TgtNode = list_to_binary(atom_to_list('[email protected]')),
+ create_purge_checkpoint(DbName, 0, TgtNode),
+
+ % Add a local node rev to the list of node revs. It should
+ % be filtered out
+ {Pos, [Rev | _]} = OldDoc#doc.revs,
+ RROpts = [{read_repair, [
+ {tgt_node(), [{Pos, Rev}]},
+ {node(), [{1, <<"123">>}]}
+ ]}],
+ rpc_update_doc(DbName, OldDoc, RROpts),
+
+ ?assertEqual({ok, OldDoc}, open_doc(DbName, DocId)).
+
+
t_no_filter_after_repl({DbName, DocId, OldDoc, PSeq}) ->
?assertEqual({not_found, missing}, open_doc(DbName, DocId)),
create_purge_checkpoint(DbName, PSeq),
@@ -282,4 +304,4 @@ tgt_node() ->
tgt_node_bin() ->
- iolist_to_binary(atom_to_list(tgt_node())).
\ No newline at end of file
+ iolist_to_binary(atom_to_list(tgt_node())).