Search in sources :

Example 1 with CountDown

use of org.elasticsearch.common.util.concurrent.CountDown in project elasticsearch by elastic.

the class SyncedFlushService method attemptSyncedFlush.

/**
     * a utility method to perform a synced flush for all shards of multiple indices. see {@link #attemptSyncedFlush(ShardId, ActionListener)}
     * for more details.
     */
public void attemptSyncedFlush(final String[] aliasesOrIndices, IndicesOptions indicesOptions, final ActionListener<SyncedFlushResponse> listener) {
    final ClusterState state = clusterService.state();
    final Index[] concreteIndices = indexNameExpressionResolver.concreteIndices(state, indicesOptions, aliasesOrIndices);
    final Map<String, List<ShardsSyncedFlushResult>> results = ConcurrentCollections.newConcurrentMap();
    int numberOfShards = 0;
    for (Index index : concreteIndices) {
        final IndexMetaData indexMetaData = state.metaData().getIndexSafe(index);
        numberOfShards += indexMetaData.getNumberOfShards();
        results.put(index.getName(), Collections.synchronizedList(new ArrayList<>()));
    }
    if (numberOfShards == 0) {
        listener.onResponse(new SyncedFlushResponse(results));
        return;
    }
    final CountDown countDown = new CountDown(numberOfShards);
    for (final Index concreteIndex : concreteIndices) {
        final String index = concreteIndex.getName();
        final IndexMetaData indexMetaData = state.metaData().getIndexSafe(concreteIndex);
        final int indexNumberOfShards = indexMetaData.getNumberOfShards();
        for (int shard = 0; shard < indexNumberOfShards; shard++) {
            final ShardId shardId = new ShardId(indexMetaData.getIndex(), shard);
            innerAttemptSyncedFlush(shardId, state, new ActionListener<ShardsSyncedFlushResult>() {

                @Override
                public void onResponse(ShardsSyncedFlushResult syncedFlushResult) {
                    results.get(index).add(syncedFlushResult);
                    if (countDown.countDown()) {
                        listener.onResponse(new SyncedFlushResponse(results));
                    }
                }

                @Override
                public void onFailure(Exception e) {
                    logger.debug("{} unexpected error while executing synced flush", shardId);
                    final int totalShards = indexMetaData.getNumberOfReplicas() + 1;
                    results.get(index).add(new ShardsSyncedFlushResult(shardId, totalShards, e.getMessage()));
                    if (countDown.countDown()) {
                        listener.onResponse(new SyncedFlushResponse(results));
                    }
                }
            });
        }
    }
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) ArrayList(java.util.ArrayList) Index(org.elasticsearch.index.Index) CountDown(org.elasticsearch.common.util.concurrent.CountDown) ElasticsearchException(org.elasticsearch.ElasticsearchException) IndexClosedException(org.elasticsearch.indices.IndexClosedException) ShardNotFoundException(org.elasticsearch.index.shard.ShardNotFoundException) IndexNotFoundException(org.elasticsearch.index.IndexNotFoundException) IOException(java.io.IOException) TransportException(org.elasticsearch.transport.TransportException) IndexMetaData(org.elasticsearch.cluster.metadata.IndexMetaData) ShardId(org.elasticsearch.index.shard.ShardId) SyncedFlushResponse(org.elasticsearch.action.admin.indices.flush.SyncedFlushResponse) ArrayList(java.util.ArrayList) List(java.util.List)

Example 2 with CountDown

use of org.elasticsearch.common.util.concurrent.CountDown in project crate by crate.

the class TransportBroadcastReplicationAction method doExecute.

@Override
protected void doExecute(Request request, ActionListener<Response> listener) {
    final ClusterState clusterState = clusterService.state();
    List<ShardId> shards = shards(request, clusterState);
    final CopyOnWriteArrayList<ShardResponse> shardsResponses = new CopyOnWriteArrayList<>();
    if (shards.size() == 0) {
        finishAndNotifyListener(listener, shardsResponses);
    }
    final CountDown responsesCountDown = new CountDown(shards.size());
    for (final ShardId shardId : shards) {
        ActionListener<ShardResponse> shardActionListener = new ActionListener<ShardResponse>() {

            @Override
            public void onResponse(ShardResponse shardResponse) {
                shardsResponses.add(shardResponse);
                logger.trace("{}: got response from {}", actionName, shardId);
                if (responsesCountDown.countDown()) {
                    finishAndNotifyListener(listener, shardsResponses);
                }
            }

            @Override
            public void onFailure(Exception e) {
                logger.trace("{}: got failure from {}", actionName, shardId);
                int totalNumCopies = clusterState.getMetadata().getIndexSafe(shardId.getIndex()).getNumberOfReplicas() + 1;
                ShardResponse shardResponse = newShardResponse();
                ReplicationResponse.ShardInfo.Failure[] failures;
                if (TransportActions.isShardNotAvailableException(e)) {
                    failures = new ReplicationResponse.ShardInfo.Failure[0];
                } else {
                    ReplicationResponse.ShardInfo.Failure failure = new ReplicationResponse.ShardInfo.Failure(shardId, null, e, ExceptionsHelper.status(e), true);
                    failures = new ReplicationResponse.ShardInfo.Failure[totalNumCopies];
                    Arrays.fill(failures, failure);
                }
                shardResponse.setShardInfo(new ReplicationResponse.ShardInfo(totalNumCopies, 0, failures));
                shardsResponses.add(shardResponse);
                if (responsesCountDown.countDown()) {
                    finishAndNotifyListener(listener, shardsResponses);
                }
            }
        };
        shardExecute(request, shardId, shardActionListener);
    }
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) CountDown(org.elasticsearch.common.util.concurrent.CountDown) DefaultShardOperationFailedException(org.elasticsearch.action.support.DefaultShardOperationFailedException) BroadcastShardOperationFailedException(org.elasticsearch.action.support.broadcast.BroadcastShardOperationFailedException) ShardId(org.elasticsearch.index.shard.ShardId) ActionListener(org.elasticsearch.action.ActionListener) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList)

Example 3 with CountDown

use of org.elasticsearch.common.util.concurrent.CountDown in project crate by crate.

the class SyncedFlushService method attemptSyncedFlush.

/**
 * a utility method to perform a synced flush for all shards of multiple indices. see {@link #attemptSyncedFlush(ShardId, ActionListener)}
 * for more details.
 */
public void attemptSyncedFlush(final String[] aliasesOrIndices, IndicesOptions indicesOptions, final ActionListener<SyncedFlushResponse> listener) {
    final ClusterState state = clusterService.state();
    if (state.nodes().getMinNodeVersion().onOrAfter(Version.V_4_4_0)) {
        DEPRECATION_LOGGER.deprecatedAndMaybeLog("synced_flush", SYNCED_FLUSH_DEPRECATION_MESSAGE);
    }
    final Index[] concreteIndices = indexNameExpressionResolver.concreteIndices(state, indicesOptions, aliasesOrIndices);
    final Map<String, List<ShardsSyncedFlushResult>> results = ConcurrentCollections.newConcurrentMap();
    int numberOfShards = 0;
    for (Index index : concreteIndices) {
        final IndexMetadata indexMetadata = state.metadata().getIndexSafe(index);
        numberOfShards += indexMetadata.getNumberOfShards();
        results.put(index.getName(), Collections.synchronizedList(new ArrayList<>()));
    }
    if (numberOfShards == 0) {
        listener.onResponse(new SyncedFlushResponse(results));
        return;
    }
    final CountDown countDown = new CountDown(numberOfShards);
    for (final Index concreteIndex : concreteIndices) {
        final String index = concreteIndex.getName();
        final IndexMetadata indexMetadata = state.metadata().getIndexSafe(concreteIndex);
        final int indexNumberOfShards = indexMetadata.getNumberOfShards();
        for (int shard = 0; shard < indexNumberOfShards; shard++) {
            final ShardId shardId = new ShardId(indexMetadata.getIndex(), shard);
            innerAttemptSyncedFlush(shardId, state, new ActionListener<ShardsSyncedFlushResult>() {

                @Override
                public void onResponse(ShardsSyncedFlushResult syncedFlushResult) {
                    results.get(index).add(syncedFlushResult);
                    if (countDown.countDown()) {
                        listener.onResponse(new SyncedFlushResponse(results));
                    }
                }

                @Override
                public void onFailure(Exception e) {
                    LOGGER.debug("{} unexpected error while executing synced flush", shardId);
                    final int totalShards = indexMetadata.getNumberOfReplicas() + 1;
                    results.get(index).add(new ShardsSyncedFlushResult(shardId, totalShards, e.getMessage()));
                    if (countDown.countDown()) {
                        listener.onResponse(new SyncedFlushResponse(results));
                    }
                }
            });
        }
    }
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) ArrayList(java.util.ArrayList) Index(org.elasticsearch.index.Index) CountDown(org.elasticsearch.common.util.concurrent.CountDown) ElasticsearchException(org.elasticsearch.ElasticsearchException) IndexClosedException(org.elasticsearch.indices.IndexClosedException) ShardNotFoundException(org.elasticsearch.index.shard.ShardNotFoundException) IndexNotFoundException(org.elasticsearch.index.IndexNotFoundException) TransportException(org.elasticsearch.transport.TransportException) IOException(java.io.IOException) ShardId(org.elasticsearch.index.shard.ShardId) SyncedFlushResponse(org.elasticsearch.action.admin.indices.flush.SyncedFlushResponse) List(java.util.List) ArrayList(java.util.ArrayList) IndexMetadata(org.elasticsearch.cluster.metadata.IndexMetadata)

Example 4 with CountDown

use of org.elasticsearch.common.util.concurrent.CountDown in project elasticsearch by elastic.

the class RemoteClusterService method updateRemoteClusters.

/**
     * This method updates the list of remote clusters. It's intended to be used as an update consumer on the settings infrastructure
     * @param seeds a cluster alias to discovery node mapping representing the remote clusters seeds nodes
     * @param connectionListener a listener invoked once every configured cluster has been connected to
     */
private synchronized void updateRemoteClusters(Map<String, List<DiscoveryNode>> seeds, ActionListener<Void> connectionListener) {
    if (seeds.containsKey(LOCAL_CLUSTER_GROUP_KEY)) {
        throw new IllegalArgumentException("remote clusters must not have the empty string as its key");
    }
    Map<String, RemoteClusterConnection> remoteClusters = new HashMap<>();
    if (seeds.isEmpty()) {
        connectionListener.onResponse(null);
    } else {
        CountDown countDown = new CountDown(seeds.size());
        Predicate<DiscoveryNode> nodePredicate = (node) -> Version.CURRENT.isCompatible(node.getVersion());
        if (REMOTE_NODE_ATTRIBUTE.exists(settings)) {
            // nodes can be tagged with node.attr.remote_gateway: true to allow a node to be a gateway node for
            // cross cluster search
            String attribute = REMOTE_NODE_ATTRIBUTE.get(settings);
            nodePredicate = nodePredicate.and((node) -> Boolean.getBoolean(node.getAttributes().getOrDefault(attribute, "false")));
        }
        remoteClusters.putAll(this.remoteClusters);
        for (Map.Entry<String, List<DiscoveryNode>> entry : seeds.entrySet()) {
            RemoteClusterConnection remote = this.remoteClusters.get(entry.getKey());
            if (entry.getValue().isEmpty()) {
                // with no seed nodes we just remove the connection
                try {
                    IOUtils.close(remote);
                } catch (IOException e) {
                    logger.warn("failed to close remote cluster connections for cluster: " + entry.getKey(), e);
                }
                remoteClusters.remove(entry.getKey());
                continue;
            }
            if (remote == null) {
                // this is a new cluster we have to add a new representation
                remote = new RemoteClusterConnection(settings, entry.getKey(), entry.getValue(), transportService, numRemoteConnections, nodePredicate);
                remoteClusters.put(entry.getKey(), remote);
            }
            // now update the seed nodes no matter if it's new or already existing
            RemoteClusterConnection finalRemote = remote;
            remote.updateSeedNodes(entry.getValue(), ActionListener.wrap(response -> {
                if (countDown.countDown()) {
                    connectionListener.onResponse(response);
                }
            }, exception -> {
                if (countDown.fastForward()) {
                    connectionListener.onFailure(exception);
                }
                if (finalRemote.isClosed() == false) {
                    logger.warn("failed to update seed list for cluster: " + entry.getKey(), exception);
                }
            }));
        }
    }
    this.remoteClusters = Collections.unmodifiableMap(remoteClusters);
}
Also used : ShardId(org.elasticsearch.index.shard.ShardId) Arrays(java.util.Arrays) ShardIterator(org.elasticsearch.cluster.routing.ShardIterator) TimeoutException(java.util.concurrent.TimeoutException) PlainShardIterator(org.elasticsearch.cluster.routing.PlainShardIterator) HashMap(java.util.HashMap) Index(org.elasticsearch.index.Index) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Strings(org.elasticsearch.common.Strings) ArrayList(java.util.ArrayList) InetAddress(java.net.InetAddress) DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) Settings(org.elasticsearch.common.settings.Settings) TimeValue(org.elasticsearch.common.unit.TimeValue) Map(java.util.Map) CountDown(org.elasticsearch.common.util.concurrent.CountDown) TransportService(org.elasticsearch.transport.TransportService) ClusterSearchShardsGroup(org.elasticsearch.action.admin.cluster.shards.ClusterSearchShardsGroup) Transport(org.elasticsearch.transport.Transport) AbstractComponent(org.elasticsearch.common.component.AbstractComponent) Setting(org.elasticsearch.common.settings.Setting) Predicate(java.util.function.Predicate) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IOUtils(org.apache.lucene.util.IOUtils) IOException(java.io.IOException) InetSocketAddress(java.net.InetSocketAddress) UnknownHostException(java.net.UnknownHostException) Collectors(java.util.stream.Collectors) ClusterSearchShardsResponse(org.elasticsearch.action.admin.cluster.shards.ClusterSearchShardsResponse) TimeUnit(java.util.concurrent.TimeUnit) AliasFilter(org.elasticsearch.search.internal.AliasFilter) List(java.util.List) Version(org.elasticsearch.Version) Stream(java.util.stream.Stream) TransportAddress(org.elasticsearch.common.transport.TransportAddress) Supplier(org.apache.logging.log4j.util.Supplier) Closeable(java.io.Closeable) TransportException(org.elasticsearch.transport.TransportException) Collections(java.util.Collections) ActionListener(org.elasticsearch.action.ActionListener) DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IOException(java.io.IOException) CountDown(org.elasticsearch.common.util.concurrent.CountDown) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 5 with CountDown

use of org.elasticsearch.common.util.concurrent.CountDown in project elasticsearch by elastic.

the class RemoteClusterService method collectSearchShards.

void collectSearchShards(SearchRequest searchRequest, Map<String, List<String>> remoteIndicesByCluster, ActionListener<Map<String, ClusterSearchShardsResponse>> listener) {
    final CountDown responsesCountDown = new CountDown(remoteIndicesByCluster.size());
    final Map<String, ClusterSearchShardsResponse> searchShardsResponses = new ConcurrentHashMap<>();
    final AtomicReference<TransportException> transportException = new AtomicReference<>();
    for (Map.Entry<String, List<String>> entry : remoteIndicesByCluster.entrySet()) {
        final String clusterName = entry.getKey();
        RemoteClusterConnection remoteClusterConnection = remoteClusters.get(clusterName);
        if (remoteClusterConnection == null) {
            throw new IllegalArgumentException("no such remote cluster: " + clusterName);
        }
        final List<String> indices = entry.getValue();
        remoteClusterConnection.fetchSearchShards(searchRequest, indices, new ActionListener<ClusterSearchShardsResponse>() {

            @Override
            public void onResponse(ClusterSearchShardsResponse clusterSearchShardsResponse) {
                searchShardsResponses.put(clusterName, clusterSearchShardsResponse);
                if (responsesCountDown.countDown()) {
                    TransportException exception = transportException.get();
                    if (exception == null) {
                        listener.onResponse(searchShardsResponses);
                    } else {
                        listener.onFailure(transportException.get());
                    }
                }
            }

            @Override
            public void onFailure(Exception e) {
                TransportException exception = new TransportException("unable to communicate with remote cluster [" + clusterName + "]", e);
                if (transportException.compareAndSet(null, exception) == false) {
                    exception = transportException.accumulateAndGet(exception, (previous, current) -> {
                        current.addSuppressed(previous);
                        return current;
                    });
                }
                if (responsesCountDown.countDown()) {
                    listener.onFailure(exception);
                }
            }
        });
    }
}
Also used : ClusterSearchShardsResponse(org.elasticsearch.action.admin.cluster.shards.ClusterSearchShardsResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDown(org.elasticsearch.common.util.concurrent.CountDown) TransportException(org.elasticsearch.transport.TransportException) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) TransportException(org.elasticsearch.transport.TransportException) ArrayList(java.util.ArrayList) List(java.util.List) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Aggregations

CountDown (org.elasticsearch.common.util.concurrent.CountDown)11 TransportException (org.elasticsearch.transport.TransportException)8 IOException (java.io.IOException)7 ArrayList (java.util.ArrayList)5 DiscoveryNode (org.elasticsearch.cluster.node.DiscoveryNode)5 ShardId (org.elasticsearch.index.shard.ShardId)5 List (java.util.List)4 ParameterizedMessage (org.apache.logging.log4j.message.ParameterizedMessage)4 ShardRouting (org.elasticsearch.cluster.routing.ShardRouting)4 Supplier (org.apache.logging.log4j.util.Supplier)3 ActionListener (org.elasticsearch.action.ActionListener)3 ClusterState (org.elasticsearch.cluster.ClusterState)3 UnknownHostException (java.net.UnknownHostException)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)2 TimeoutException (java.util.concurrent.TimeoutException)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 ElasticsearchException (org.elasticsearch.ElasticsearchException)2