Internal: extract gateway required allocation calculations

and add a basic test

Closes #13391
This commit is contained in:
Boaz Leskes 2015-09-08 12:18:08 +02:00
parent 37d4727c0a
commit 30ca6d3970
2 changed files with 97 additions and 25 deletions

View File

@ -32,7 +32,6 @@ import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.NodeEnvironment;
import java.nio.file.Path;
/**
@ -73,30 +72,8 @@ public class Gateway extends AbstractComponent implements ClusterStateListener {
TransportNodesListGatewayMetaState.NodesGatewayMetaState nodesState = listGatewayMetaState.list(nodesIds.toArray(String.class), null).actionGet();
int requiredAllocation = 1;
try {
if ("quorum".equals(initialMeta)) {
if (nodesIds.size() > 2) {
requiredAllocation = (nodesIds.size() / 2) + 1;
}
} else if ("quorum-1".equals(initialMeta) || "half".equals(initialMeta)) {
if (nodesIds.size() > 2) {
requiredAllocation = ((1 + nodesIds.size()) / 2);
}
} else if ("one".equals(initialMeta)) {
requiredAllocation = 1;
} else if ("full".equals(initialMeta) || "all".equals(initialMeta)) {
requiredAllocation = nodesIds.size();
} else if ("full-1".equals(initialMeta) || "all-1".equals(initialMeta)) {
if (nodesIds.size() > 1) {
requiredAllocation = nodesIds.size() - 1;
}
} else {
requiredAllocation = Integer.parseInt(initialMeta);
}
} catch (Exception e) {
logger.warn("failed to derived initial_meta from value {}", initialMeta);
}
int requiredAllocation = calcRequiredAllocations(this.initialMeta, nodesIds.size());
if (nodesState.failures().length > 0) {
for (FailedNodeException failedNodeException : nodesState.failures()) {
@ -163,6 +140,34 @@ public class Gateway extends AbstractComponent implements ClusterStateListener {
listener.onSuccess(builder.build());
}
protected int calcRequiredAllocations(final String setting, final int nodeCount) {
int requiredAllocation = 1;
try {
if ("quorum".equals(setting)) {
if (nodeCount > 2) {
requiredAllocation = (nodeCount / 2) + 1;
}
} else if ("quorum-1".equals(setting) || "half".equals(setting)) {
if (nodeCount > 2) {
requiredAllocation = ((1 + nodeCount) / 2);
}
} else if ("one".equals(setting)) {
requiredAllocation = 1;
} else if ("full".equals(setting) || "all".equals(setting)) {
requiredAllocation = nodeCount;
} else if ("full-1".equals(setting) || "all-1".equals(setting)) {
if (nodeCount > 1) {
requiredAllocation = nodeCount - 1;
}
} else {
requiredAllocation = Integer.parseInt(setting);
}
} catch (Exception e) {
logger.warn("failed to derived initial_meta from value {}", setting);
}
return requiredAllocation;
}
public void reset() throws Exception {
try {
Path[] dataPaths = nodeEnv.nodeDataPaths();

View File

@ -0,0 +1,67 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.gateway;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.cluster.TestClusterService;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;
public class GatewayTests extends ESTestCase {
public void testCalcRequiredAllocations() {
MockGateway gateway = new MockGateway(Settings.EMPTY, new TestClusterService());
int nodeCount = randomIntBetween(1, 6);
Map<String, Integer> expectedResult = new HashMap<>();
expectedResult.put("quorum", nodeCount > 2 ? nodeCount / 2 + 1 : 1);
expectedResult.put("quorum-1", nodeCount > 2 ? (nodeCount + 1) / 2 : 1);
expectedResult.put("half", expectedResult.get("quorum-1"));
expectedResult.put("one", 1);
expectedResult.put("full", nodeCount);
expectedResult.put("all", nodeCount);
expectedResult.put("full-1", Math.max(1, nodeCount - 1));
expectedResult.put("all-1", Math.max(1, nodeCount - 1));
int i = randomIntBetween(1, 20);
expectedResult.put("" + i, i);
expectedResult.put(randomUnicodeOfCodepointLength(10), 1);
for (String setting : expectedResult.keySet()) {
assertThat("unexpected result for setting [" + setting + "]", gateway.calcRequiredAllocations(setting, nodeCount), equalTo(expectedResult.get(setting).intValue()));
}
}
static class MockGateway extends Gateway {
MockGateway(Settings settings, ClusterService clusterService) {
super(settings, clusterService, null, null, null, ClusterName.DEFAULT);
}
@Override
public int calcRequiredAllocations(String setting, int nodeCount) {
return super.calcRequiredAllocations(setting, nodeCount);
}
}
}