Skip to content

Commit c398715

Browse files
authored
Remove local discovery in favor of a simpler MockZenPings (#20960)
`LocalDiscovery` is a discovery implementation that uses static in memory maps to keep track of current live nodes. This is used extensively in our tests in order to speed up cluster formation (i.e., shortcut the 3 second ping period used by `ZenDiscovery` by default). This is sad as that mean that most of the test run using a different discovery semantics than what is used in production. Instead of replacing the entire discovery logic, we can use a similar approach to only shortcut the pinging components.
1 parent dca614a commit c398715

File tree

29 files changed

+325
-786
lines changed

29 files changed

+325
-786
lines changed

core/src/main/java/org/elasticsearch/cluster/ClusterState.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
import org.elasticsearch.common.xcontent.XContentFactory;
5353
import org.elasticsearch.common.xcontent.XContentParser;
5454
import org.elasticsearch.discovery.Discovery;
55-
import org.elasticsearch.discovery.local.LocalDiscovery;
5655
import org.elasticsearch.discovery.zen.publish.PublishClusterStateAction;
5756

5857
import java.io.IOException;
@@ -72,8 +71,7 @@
7271
* single thread and controlled by the {@link ClusterService}. After every update the
7372
* {@link Discovery#publish} method publishes new version of the cluster state to all other nodes in the
7473
* cluster. The actual publishing mechanism is delegated to the {@link Discovery#publish} method and depends on
75-
* the type of discovery. For example, for local discovery it is implemented by the {@link LocalDiscovery#publish}
76-
* method. In the Zen Discovery it is handled in the {@link PublishClusterStateAction#publish} method. The
74+
* the type of discovery. In the Zen Discovery it is handled in the {@link PublishClusterStateAction#publish} method. The
7775
* publishing mechanism can be overridden by other discovery.
7876
* <p>
7977
* The cluster state implements the {@link Diffable} interface in order to support publishing of cluster state

core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/MaxRetryAllocationDecider.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,30 @@ public MaxRetryAllocationDecider(Settings settings) {
5454

5555
@Override
5656
public Decision canAllocate(ShardRouting shardRouting, RoutingAllocation allocation) {
57-
UnassignedInfo unassignedInfo = shardRouting.unassignedInfo();
57+
final UnassignedInfo unassignedInfo = shardRouting.unassignedInfo();
58+
final Decision decision;
5859
if (unassignedInfo != null && unassignedInfo.getNumFailedAllocations() > 0) {
5960
final IndexMetaData indexMetaData = allocation.metaData().getIndexSafe(shardRouting.index());
6061
final int maxRetry = SETTING_ALLOCATION_MAX_RETRY.get(indexMetaData.getSettings());
6162
if (allocation.isRetryFailed()) { // manual allocation - retry
6263
// if we are called via the _reroute API we ignore the failure counter and try to allocate
6364
// this improves the usability since people don't need to raise the limits to issue retries since a simple _reroute call is
6465
// enough to manually retry.
65-
return allocation.decision(Decision.YES, NAME, "shard has already failed allocating ["
66+
decision = allocation.decision(Decision.YES, NAME, "shard has already failed allocating ["
6667
+ unassignedInfo.getNumFailedAllocations() + "] times vs. [" + maxRetry + "] retries allowed "
6768
+ unassignedInfo.toString() + " - retrying once on manual allocation");
6869
} else if (unassignedInfo.getNumFailedAllocations() >= maxRetry) {
69-
return allocation.decision(Decision.NO, NAME, "shard has already failed allocating ["
70+
decision = allocation.decision(Decision.NO, NAME, "shard has already failed allocating ["
7071
+ unassignedInfo.getNumFailedAllocations() + "] times vs. [" + maxRetry + "] retries allowed "
7172
+ unassignedInfo.toString() + " - manually call [/_cluster/reroute?retry_failed=true] to retry");
73+
} else {
74+
decision = allocation.decision(Decision.YES, NAME, "shard has already failed allocating ["
75+
+ unassignedInfo.getNumFailedAllocations() + "] times but [" + maxRetry + "] retries are allowed");
7276
}
77+
} else {
78+
decision = allocation.decision(Decision.YES, NAME, "shard has no previous failures");
7379
}
74-
return allocation.decision(Decision.YES, NAME, "shard has no previous failures");
80+
return decision;
7581
}
7682

7783
@Override

core/src/main/java/org/elasticsearch/common/util/ExtensionPoint.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ protected void bindExtensions(Binder binder) {
200200
allocationMultibinder.addBinding().to(clazz);
201201
}
202202
}
203+
204+
public boolean isEmpty() {
205+
return extensions.isEmpty();
206+
}
203207
}
204208

205209
/**

core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import org.elasticsearch.common.settings.Setting.Property;
2626
import org.elasticsearch.common.settings.Settings;
2727
import org.elasticsearch.common.util.ExtensionPoint;
28-
import org.elasticsearch.discovery.local.LocalDiscovery;
2928
import org.elasticsearch.discovery.zen.ElectMasterService;
3029
import org.elasticsearch.discovery.zen.ZenDiscovery;
3130
import org.elasticsearch.discovery.zen.ping.ZenPing;
@@ -59,11 +58,9 @@ public class DiscoveryModule extends AbstractModule {
5958

6059
public DiscoveryModule(Settings settings) {
6160
this.settings = settings;
62-
addDiscoveryType("local", LocalDiscovery.class);
61+
addDiscoveryType("none", NoneDiscovery.class);
6362
addDiscoveryType("zen", ZenDiscovery.class);
6463
addElectMasterService("zen", ElectMasterService.class);
65-
// always add the unicast hosts, or things get angry!
66-
addZenPing(UnicastZenPing.class);
6764
}
6865

6966
/**
@@ -113,7 +110,7 @@ protected void configure() {
113110
throw new IllegalArgumentException("Unknown Discovery type [" + discoveryType + "]");
114111
}
115112

116-
if (discoveryType.equals("local") == false) {
113+
if (discoveryType.equals("none") == false) {
117114
String masterServiceTypeKey = ZEN_MASTER_SERVICE_TYPE_SETTING.get(settings);
118115
final Class<? extends ElectMasterService> masterService = masterServiceType.get(masterServiceTypeKey);
119116
if (masterService == null) {
@@ -130,6 +127,9 @@ protected void configure() {
130127
unicastHostProviders.getOrDefault(discoveryType, Collections.emptyList())) {
131128
unicastHostsProviderMultibinder.addBinding().to(unicastHostProvider);
132129
}
130+
if (zenPings.isEmpty()) {
131+
zenPings.registerExtension(UnicastZenPing.class);
132+
}
133133
zenPings.bind(binder());
134134
}
135135
bind(Discovery.class).to(discoveryClass).asEagerSingleton();
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.elasticsearch.discovery;
20+
21+
import org.elasticsearch.cluster.ClusterChangedEvent;
22+
import org.elasticsearch.cluster.node.DiscoveryNode;
23+
import org.elasticsearch.cluster.routing.allocation.AllocationService;
24+
import org.elasticsearch.cluster.service.ClusterService;
25+
import org.elasticsearch.common.component.AbstractLifecycleComponent;
26+
import org.elasticsearch.common.inject.Inject;
27+
import org.elasticsearch.common.settings.ClusterSettings;
28+
import org.elasticsearch.common.settings.Settings;
29+
import org.elasticsearch.discovery.zen.ElectMasterService;
30+
31+
/**
32+
* A {@link Discovery} implementation that is used by {@link org.elasticsearch.tribe.TribeService}. This implementation
33+
* doesn't support any clustering features. Most notably {@link #startInitialJoin()} does nothing and
34+
* {@link #publish(ClusterChangedEvent, AckListener)} is not supported.
35+
*/
36+
public class NoneDiscovery extends AbstractLifecycleComponent implements Discovery {
37+
38+
private final ClusterService clusterService;
39+
private final DiscoverySettings discoverySettings;
40+
41+
@Inject
42+
public NoneDiscovery(Settings settings, ClusterService clusterService, ClusterSettings clusterSettings) {
43+
super(settings);
44+
this.clusterService = clusterService;
45+
this.discoverySettings = new DiscoverySettings(settings, clusterSettings);
46+
}
47+
48+
@Override
49+
public DiscoveryNode localNode() {
50+
return clusterService.localNode();
51+
}
52+
53+
@Override
54+
public String nodeDescription() {
55+
return clusterService.getClusterName().value() + "/" + clusterService.localNode().getId();
56+
}
57+
58+
@Override
59+
public void setAllocationService(AllocationService allocationService) {
60+
61+
}
62+
63+
@Override
64+
public void publish(ClusterChangedEvent clusterChangedEvent, AckListener ackListener) {
65+
throw new UnsupportedOperationException();
66+
}
67+
68+
@Override
69+
public DiscoveryStats stats() {
70+
return null;
71+
}
72+
73+
@Override
74+
public DiscoverySettings getDiscoverySettings() {
75+
return discoverySettings;
76+
}
77+
78+
@Override
79+
public void startInitialJoin() {
80+
81+
}
82+
83+
@Override
84+
public int getMinimumMasterNodes() {
85+
return ElectMasterService.DISCOVERY_ZEN_MINIMUM_MASTER_NODES_SETTING.get(settings);
86+
}
87+
88+
@Override
89+
protected void doStart() {
90+
91+
}
92+
93+
@Override
94+
protected void doStop() {
95+
96+
}
97+
98+
@Override
99+
protected void doClose() {
100+
101+
}
102+
}

0 commit comments

Comments
 (0)