You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2019/03/04 22:07:04 UTC

[couchdb] branch shard-split updated: [fixup|fabric_ring] Remove assumption that fabric_ring always gets a full ring

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

vatamane pushed a commit to branch shard-split
in repository https://gitbox.apache.org/repos/asf/couchdb.git


The following commit(s) were added to refs/heads/shard-split by this push:
     new 3acda5c  [fixup|fabric_ring] Remove assumption that fabric_ring always gets a full ring
3acda5c is described below

commit 3acda5cd0b87558cf4ec51422bd48a7b69541a76
Author: Nick Vatamaniuc <va...@apache.org>
AuthorDate: Mon Mar 4 17:05:55 2019 -0500

    [fixup|fabric_ring] Remove assumption that fabric_ring always gets a full ring
    
    This is not the case when querying partitioned views for example
---
 src/fabric/src/fabric_ring.erl | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/src/fabric/src/fabric_ring.erl b/src/fabric/src/fabric_ring.erl
index 8426a1a..668249a 100644
--- a/src/fabric/src/fabric_ring.erl
+++ b/src/fabric/src/fabric_ring.erl
@@ -91,7 +91,8 @@ handle_response(Shard, Response, Workers, Responses, CleanupCb) ->
     #shard{range = [B, E]} = Shard,
     Responses1 = [{{B, E}, Shard, Response} | Responses],
     ResponseRanges = lists:map(fun({R, _, _}) -> R end, Responses1),
-    case mem3_util:get_ring(ResponseRanges) of
+    {MinB, MaxE} = get_range_bounds(Workers, ResponseRanges),
+    case mem3_util:get_ring(ResponseRanges, MinB, MaxE) of
         [] ->
             {ok, {Workers1, Responses1}};
         Ring ->
@@ -114,7 +115,9 @@ handle_response(Shard, Response, Workers, Responses, CleanupCb) ->
     boolean().
 is_progress_possible(Counters, Responses) ->
     ResponseRanges = lists:map(fun({{B, E}, _, _}) -> {B, E} end, Responses),
-    mem3_util:get_ring(get_worker_ranges(Counters) ++ ResponseRanges) =/= [].
+    {MinB, MaxE} = get_range_bounds(Counters, ResponseRanges),
+    Ranges = get_worker_ranges(Counters) ++ ResponseRanges,
+    mem3_util:get_ring(Ranges, MinB, MaxE) =/= [].
 
 
 get_shard_replacements_int(UnusedShards, UsedShards) ->
@@ -149,6 +152,12 @@ get_worker_ranges(Workers) ->
     lists:usort(Ranges).
 
 
+get_range_bounds(Workers, ResponseRanges) ->
+    Ranges = get_worker_ranges(Workers) ++ ResponseRanges,
+    {Bs, Es} = lists:unzip(Ranges),
+    {lists:min(Bs), lists:max(Es)}.
+
+
 get_responses([], _) ->
     [];
 
@@ -234,6 +243,22 @@ handle_response_basic_test() ->
     ?assertEqual({stop, [{Shard1, 42}, {Shard2, 43}]}, Result2).
 
 
+handle_response_incomplete_ring_test() ->
+    Shard1 = mk_shard("n1", [0, 1]),
+    Shard2 = mk_shard("n1", [2, 10]),
+
+    Workers1 = fabric_dict:init([Shard1, Shard2], nil),
+
+    Result1 = handle_response(Shard1, 42, Workers1, [], undefined),
+    ?assertMatch({ok, {_, _}}, Result1),
+    {ok, {Workers2, Responses1}} = Result1,
+    ?assertEqual(fabric_dict:erase(Shard1, Workers1), Workers2),
+    ?assertEqual([{{0, 1}, Shard1, 42}], Responses1),
+
+    Result2 = handle_response(Shard2, 43, Workers2, Responses1, undefined),
+    ?assertEqual({stop, [{Shard1, 42}, {Shard2, 43}]}, Result2).
+
+
 handle_response_test_multiple_copies_test() ->
     Shard1 = mk_shard("n1", [0, 1]),
     Shard2 = mk_shard("n2", [0, 1]),