Skip to content

Commit

Permalink
ActiveShardCount should not fail when closing the index (#35936)
Browse files Browse the repository at this point in the history
The ActiveShardCount is used by cluster state observers to wait for a 
given number of shards to be active before returning to the caller. The 
current implementation does not work when an index is closed while an 
observer is waiting on shards to be active. In this case, a NPE is thrown 
and the observer is never notified that the shards won't become active.

This commit fixes the ActiveShardCount.enoughShardsActive() so that it 
does not fail when an index is closed, similarly to what is done when an 
index is deleted.
  • Loading branch information
tlrx committed Nov 29, 2018
1 parent 5c28147 commit 5c17b2f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
Expand Up @@ -155,6 +155,12 @@ public boolean enoughShardsActive(final ClusterState clusterState, final String.
continue;
}
final IndexRoutingTable indexRoutingTable = clusterState.routingTable().index(indexName);
if (indexRoutingTable == null && indexMetaData.getState() == IndexMetaData.State.CLOSE) {
// its possible the index was closed while waiting for active shard copies,
// in this case, we'll just consider it that we have enough active shard copies
// and we can stop waiting
continue;
}
assert indexRoutingTable != null;
if (indexRoutingTable.allPrimaryShardsActive() == false) {
// all primary shards aren't active yet
Expand Down
Expand Up @@ -36,6 +36,7 @@

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;

/**
* Tests for the {@link ActiveShardCount} class
Expand Down Expand Up @@ -165,6 +166,17 @@ public void testEnoughShardsActiveValueBased() {
assertEquals("activeShardCount cannot be negative", e.getMessage());
}

public void testEnoughShardsActiveWithClosedIndex() {
final String indexName = "test-idx";
final int numberOfShards = randomIntBetween(1, 5);
final int numberOfReplicas = randomIntBetween(4, 7);

final ClusterState clusterState = initializeWithClosedIndex(indexName, numberOfShards, numberOfReplicas);
for (ActiveShardCount waitForActiveShards : Arrays.asList(ActiveShardCount.DEFAULT, ActiveShardCount.ALL, ActiveShardCount.ONE)) {
assertTrue(waitForActiveShards.enoughShardsActive(clusterState, indexName));
}
}

private void runTestForOneActiveShard(final ActiveShardCount activeShardCount) {
final String indexName = "test-idx";
final int numberOfShards = randomIntBetween(1, 5);
Expand Down Expand Up @@ -192,6 +204,18 @@ private ClusterState initializeWithNewIndex(final String indexName, final int nu
return ClusterState.builder(new ClusterName("test_cluster")).metaData(metaData).routingTable(routingTable).build();
}

private ClusterState initializeWithClosedIndex(final String indexName, final int numShards, final int numReplicas) {
final IndexMetaData indexMetaData = IndexMetaData.builder(indexName)
.settings(settings(Version.CURRENT)
.put(IndexMetaData.SETTING_INDEX_UUID, UUIDs.randomBase64UUID()))
.numberOfShards(numShards)
.numberOfReplicas(numReplicas)
.state(IndexMetaData.State.CLOSE)
.build();
final MetaData metaData = MetaData.builder().put(indexMetaData, true).build();
return ClusterState.builder(new ClusterName("test_cluster")).metaData(metaData).build();
}

private ClusterState startPrimaries(final ClusterState clusterState, final String indexName) {
RoutingTable routingTable = clusterState.routingTable();
IndexRoutingTable indexRoutingTable = routingTable.index(indexName);
Expand Down

0 comments on commit 5c17b2f

Please sign in to comment.