Permalink
Browse files

MB-7813 Allow replicas on transfer to be unindexable

Previosuly it was not possible to move to the unindexable state
partitions that are replicas being transferred into the main
index (marked as passive). This change now allows it, as from
an external point of view, once a replica is requested to become
active, it's seen like a regular active partition - the details
of transferring a replica are meant to be known only internally,
abstracted from callers.

Change-Id: Ife72afe0e6827427a23b4bf48fe2eb6a48481758
Reviewed-on: http://review.couchbase.org/24946
Reviewed-by: Volker Mische <volker.mische@gmail.com>
Tested-by: Filipe David Borba Manana <fdmanana@gmail.com>
  • Loading branch information...
1 parent fb6316e commit 140de2b0680abda49bb0345bac0f7019bfc4de69 @fdmanana fdmanana committed Feb 28, 2013
Showing with 159 additions and 60 deletions.
  1. +19 −16 src/couch_set_view/src/couch_set_view_group.erl
  2. +140 −44 src/couch_set_view/test/17-unindexable-partitions.t
@@ -98,6 +98,7 @@
shutdown = false :: boolean(),
shutdown_aliases :: [binary()],
auto_cleanup = true :: boolean(),
+ auto_transfer_replicas = true :: boolean(),
replica_partitions = [] :: ordsets:ordset(partition_id()),
pending_transition_waiters = [] :: [{From::{pid(), reference()}, #set_view_group_req{}}],
update_listeners = dict:new() :: dict(),
@@ -419,6 +420,10 @@ handle_call({set_auto_cleanup, Enabled}, _From, State) ->
% To be used only by unit tests.
{reply, ok, State#state{auto_cleanup = Enabled}, ?TIMEOUT};
+handle_call({set_auto_transfer_replicas, Enabled}, _From, State) ->
+ % To be used only by unit tests.
+ {reply, ok, State#state{auto_transfer_replicas = Enabled}, ?TIMEOUT};
+
handle_call({define_view, NumPartitions, _, _, _, _, _}, _From, State)
when (not ?is_defined(State)), NumPartitions > ?MAX_NUM_PARTITIONS ->
{reply, {error, <<"Too high value for number of partitions">>}, State};
@@ -980,8 +985,9 @@ handle_info(timeout, State) when not ?is_defined(State) ->
{noreply, State};
handle_info(timeout, #state{group = Group} = State) ->
- case (?set_replicas_on_transfer(Group) /= []) orelse
- (dict:size(State#state.update_listeners) > 0) of
+ TransferReplicas = (?set_replicas_on_transfer(Group) /= []) andalso
+ State#state.auto_transfer_replicas,
+ case TransferReplicas orelse (dict:size(State#state.update_listeners) > 0) of
true ->
{noreply, start_updater(State)};
false ->
@@ -3097,13 +3103,22 @@ process_mark_as_unindexable(#state{group = Group} = State, Partitions0) ->
PendingTrans = ?set_pending_transition(Group),
PendingActive = ?pending_transition_active(PendingTrans),
PendingPassive = ?pending_transition_passive(PendingTrans),
- Partitions = lists:filter(
+ {Partitions, Rest0} = lists:partition(
fun(PartId) ->
couch_set_view_util:has_part_seq(PartId, ?set_seqs(Group)) orelse
lists:member(PartId, PendingActive) orelse
lists:member(PartId, PendingPassive)
end,
Partitions0),
+ Rest = ordsets:from_list(Rest0),
+ case ordsets:intersection(State#state.replica_partitions, Rest) of
+ [] ->
+ ok;
+ ReplicasIntersection ->
+ ErrorMsg = io_lib:format("Intersection between requested unindexable list"
+ " and current set of replica partitions: ~w", [ReplicasIntersection]),
+ throw({error, iolist_to_binary(ErrorMsg)})
+ end,
do_process_mark_as_unindexable(State, Partitions).
@@ -3113,21 +3128,9 @@ do_process_mark_as_unindexable(State, []) ->
State;
do_process_mark_as_unindexable(State0, Partitions) ->
#state{
- group = #set_view_group{index_header = Header} = Group,
- replica_partitions = ReplicaParts
+ group = #set_view_group{index_header = Header} = Group
} = State = stop_updater(State0),
UpdaterWasRunning = is_pid(State0#state.updater_pid),
- ReplicasIntersection = [
- P || P <- Partitions, lists:member(P, ReplicaParts)
- ],
- case ReplicasIntersection of
- [] ->
- ok;
- _ ->
- ErrorMsg = io_lib:format("Intersection between requested unindexable list"
- " and current set of replica partitions: ~w", [ReplicasIntersection]),
- throw({error, iolist_to_binary(ErrorMsg)})
- end,
PendingTrans = ?set_pending_transition(Group),
PendingActive = ?pending_transition_active(PendingTrans),
Oops, something went wrong.

0 comments on commit 140de2b

Please sign in to comment.