Search in sources :

Example 1 with ListenableFuture

use of org.opensearch.common.util.concurrent.ListenableFuture in project OpenSearch by opensearch-project.

the class ClusterConnectionManager method connectToNode.

/**
 * Connects to a node with the given connection profile. If the node is already connected this method has no effect.
 * Once a successful is established, it can be validated before being exposed.
 * The ActionListener will be called on the calling thread or the generic thread pool.
 */
@Override
public void connectToNode(DiscoveryNode node, ConnectionProfile connectionProfile, ConnectionValidator connectionValidator, ActionListener<Void> listener) throws ConnectTransportException {
    ConnectionProfile resolvedProfile = ConnectionProfile.resolveConnectionProfile(connectionProfile, defaultProfile);
    if (node == null) {
        listener.onFailure(new ConnectTransportException(null, "can't connect to a null node"));
        return;
    }
    if (connectingRefCounter.tryIncRef() == false) {
        listener.onFailure(new IllegalStateException("connection manager is closed"));
        return;
    }
    if (connectedNodes.containsKey(node)) {
        connectingRefCounter.decRef();
        listener.onResponse(null);
        return;
    }
    final ListenableFuture<Void> currentListener = new ListenableFuture<>();
    final ListenableFuture<Void> existingListener = pendingConnections.putIfAbsent(node, currentListener);
    if (existingListener != null) {
        try {
            // wait on previous entry to complete connection attempt
            existingListener.addListener(listener, OpenSearchExecutors.newDirectExecutorService());
        } finally {
            connectingRefCounter.decRef();
        }
        return;
    }
    currentListener.addListener(listener, OpenSearchExecutors.newDirectExecutorService());
    final RunOnce releaseOnce = new RunOnce(connectingRefCounter::decRef);
    internalOpenConnection(node, resolvedProfile, ActionListener.wrap(conn -> {
        connectionValidator.validate(conn, resolvedProfile, ActionListener.wrap(ignored -> {
            assert Transports.assertNotTransportThread("connection validator success");
            try {
                if (connectedNodes.putIfAbsent(node, conn) != null) {
                    logger.debug("existing connection to node [{}], closing new redundant connection", node);
                    IOUtils.closeWhileHandlingException(conn);
                } else {
                    logger.debug("connected to node [{}]", node);
                    try {
                        connectionListener.onNodeConnected(node, conn);
                    } finally {
                        final Transport.Connection finalConnection = conn;
                        conn.addCloseListener(ActionListener.wrap(() -> {
                            logger.trace("unregistering {} after connection close and marking as disconnected", node);
                            connectedNodes.remove(node, finalConnection);
                            connectionListener.onNodeDisconnected(node, conn);
                        }));
                    }
                }
            } finally {
                ListenableFuture<Void> future = pendingConnections.remove(node);
                assert future == currentListener : "Listener in pending map is different than the expected listener";
                releaseOnce.run();
                future.onResponse(null);
            }
        }, e -> {
            assert Transports.assertNotTransportThread("connection validator failure");
            IOUtils.closeWhileHandlingException(conn);
            failConnectionListeners(node, releaseOnce, e, currentListener);
        }));
    }, e -> {
        assert Transports.assertNotTransportThread("internalOpenConnection failure");
        failConnectionListeners(node, releaseOnce, e, currentListener);
    }));
}
Also used : Iterator(java.util.Iterator) Set(java.util.Set) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Settings(org.opensearch.common.settings.Settings) OpenSearchExecutors(org.opensearch.common.util.concurrent.OpenSearchExecutors) RunOnce(org.opensearch.common.util.concurrent.RunOnce) ConcurrentMap(java.util.concurrent.ConcurrentMap) ConcurrentCollections(org.opensearch.common.util.concurrent.ConcurrentCollections) IOUtils(org.opensearch.core.internal.io.IOUtils) CountDownLatch(java.util.concurrent.CountDownLatch) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) Logger(org.apache.logging.log4j.Logger) AbstractRefCounted(org.opensearch.common.util.concurrent.AbstractRefCounted) Map(java.util.Map) ActionListener(org.opensearch.action.ActionListener) ListenableFuture(org.opensearch.common.util.concurrent.ListenableFuture) LogManager(org.apache.logging.log4j.LogManager) Collections(java.util.Collections) RunOnce(org.opensearch.common.util.concurrent.RunOnce) ListenableFuture(org.opensearch.common.util.concurrent.ListenableFuture)

Aggregations

Collections (java.util.Collections)1 Iterator (java.util.Iterator)1 Map (java.util.Map)1 Set (java.util.Set)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 LogManager (org.apache.logging.log4j.LogManager)1 Logger (org.apache.logging.log4j.Logger)1 ActionListener (org.opensearch.action.ActionListener)1 DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)1 Settings (org.opensearch.common.settings.Settings)1 AbstractRefCounted (org.opensearch.common.util.concurrent.AbstractRefCounted)1 ConcurrentCollections (org.opensearch.common.util.concurrent.ConcurrentCollections)1 ListenableFuture (org.opensearch.common.util.concurrent.ListenableFuture)1 OpenSearchExecutors (org.opensearch.common.util.concurrent.OpenSearchExecutors)1 RunOnce (org.opensearch.common.util.concurrent.RunOnce)1 IOUtils (org.opensearch.core.internal.io.IOUtils)1