ActiveShardCount should not fail when closing the index (#35936)
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.
This commit is contained in:
parent
45db829039
commit
0967620641
|
@ -156,6 +156,12 @@ public final class ActiveShardCount implements Writeable {
|
|||
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
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.elasticsearch.test.ESTestCase;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Tests for the {@link ActiveShardCount} class
|
||||
|
@ -165,6 +166,17 @@ public class ActiveShardCountTests extends ESTestCase {
|
|||
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);
|
||||
|
@ -192,6 +204,18 @@ public class ActiveShardCountTests extends ESTestCase {
|
|||
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);
|
||||
|
|
Loading…
Reference in New Issue