org.elasticsearch.discovery.zen.ping.ZenPingService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of elasticsearch Show documentation
Show all versions of elasticsearch Show documentation
Elasticsearch subproject :server
/*
* Licensed to Elastic Search and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Elastic Search 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.discovery.zen.ping;
import org.elasticsearch.ElasticSearchException;
import org.elasticsearch.ElasticSearchIllegalStateException;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.discovery.zen.DiscoveryNodesProvider;
import org.elasticsearch.discovery.zen.ping.multicast.MulticastZenPing;
import org.elasticsearch.discovery.zen.ping.unicast.UnicastZenPing;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
/**
* @author kimchy (shay.banon)
*/
public class ZenPingService extends AbstractLifecycleComponent implements ZenPing {
private volatile ImmutableList zenPings = ImmutableList.of();
@Inject public ZenPingService(Settings settings, ThreadPool threadPool, TransportService transportService, ClusterName clusterName, NetworkService networkService) {
super(settings);
ImmutableList.Builder zenPingsBuilder = ImmutableList.builder();
if (componentSettings.getAsBoolean("multicast.enabled", true)) {
zenPingsBuilder.add(new MulticastZenPing(settings, threadPool, transportService, clusterName, networkService));
}
// always add the unicast hosts, so it will be able to receive unicast requests even when working in multicast
zenPingsBuilder.add(new UnicastZenPing(settings, threadPool, transportService, clusterName));
this.zenPings = zenPingsBuilder.build();
}
public ImmutableList zenPings() {
return this.zenPings;
}
public void zenPings(ImmutableList pings) {
this.zenPings = pings;
if (lifecycle.started()) {
for (ZenPing zenPing : zenPings) {
zenPing.start();
}
} else if (lifecycle.stopped()) {
for (ZenPing zenPing : zenPings) {
zenPing.stop();
}
}
}
@Override public void setNodesProvider(DiscoveryNodesProvider nodesProvider) {
if (lifecycle.started()) {
throw new ElasticSearchIllegalStateException("Can't set nodes provider when started");
}
for (ZenPing zenPing : zenPings) {
zenPing.setNodesProvider(nodesProvider);
}
}
@Override protected void doStart() throws ElasticSearchException {
for (ZenPing zenPing : zenPings) {
zenPing.start();
}
}
@Override protected void doStop() throws ElasticSearchException {
for (ZenPing zenPing : zenPings) {
zenPing.stop();
}
}
@Override protected void doClose() throws ElasticSearchException {
for (ZenPing zenPing : zenPings) {
zenPing.close();
}
}
public PingResponse[] pingAndWait(TimeValue timeout) {
final AtomicReference response = new AtomicReference();
final CountDownLatch latch = new CountDownLatch(1);
ping(new PingListener() {
@Override public void onPing(PingResponse[] pings) {
response.set(pings);
latch.countDown();
}
}, timeout);
try {
latch.await();
return response.get();
} catch (InterruptedException e) {
return null;
}
}
@Override public void ping(PingListener listener, TimeValue timeout) throws ElasticSearchException {
ImmutableList zenPings = this.zenPings;
CompoundPingListener compoundPingListener = new CompoundPingListener(listener, zenPings);
for (ZenPing zenPing : zenPings) {
zenPing.ping(compoundPingListener, timeout);
}
}
private static class CompoundPingListener implements PingListener {
private final PingListener listener;
private final ImmutableList zenPings;
private final AtomicInteger counter;
private ConcurrentMap responses = new ConcurrentHashMap();
private CompoundPingListener(PingListener listener, ImmutableList zenPings) {
this.listener = listener;
this.zenPings = zenPings;
this.counter = new AtomicInteger(zenPings.size());
}
@Override public void onPing(PingResponse[] pings) {
if (pings != null) {
for (PingResponse pingResponse : pings) {
responses.put(pingResponse.target(), pingResponse);
}
}
if (counter.decrementAndGet() == 0) {
listener.onPing(responses.values().toArray(new PingResponse[responses.size()]));
}
}
}
}