Search in sources :

Example 6 with CountDown

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

the class SyncedFlushService method sendSyncRequests.

void sendSyncRequests(final String syncId, final List<ShardRouting> shards, ClusterState state, Map<String, Engine.CommitId> expectedCommitIds, final ShardId shardId, final int totalShards, final ActionListener<ShardsSyncedFlushResult> listener) {
    final CountDown countDown = new CountDown(shards.size());
    final Map<ShardRouting, ShardSyncedFlushResponse> results = ConcurrentCollections.newConcurrentMap();
    for (final ShardRouting shard : shards) {
        final DiscoveryNode node = state.nodes().get(shard.currentNodeId());
        if (node == null) {
            logger.trace("{} is assigned to an unknown node. skipping for sync id [{}]. shard routing {}", shardId, syncId, shard);
            results.put(shard, new ShardSyncedFlushResponse("unknown node"));
            contDownAndSendResponseIfDone(syncId, shards, shardId, totalShards, listener, countDown, results);
            continue;
        }
        final Engine.CommitId expectedCommitId = expectedCommitIds.get(shard.currentNodeId());
        if (expectedCommitId == null) {
            logger.trace("{} can't resolve expected commit id for current node, skipping for sync id [{}]. shard routing {}", shardId, syncId, shard);
            results.put(shard, new ShardSyncedFlushResponse("no commit id from pre-sync flush"));
            contDownAndSendResponseIfDone(syncId, shards, shardId, totalShards, listener, countDown, results);
            continue;
        }
        logger.trace("{} sending synced flush request to {}. sync id [{}].", shardId, shard, syncId);
        transportService.sendRequest(node, SYNCED_FLUSH_ACTION_NAME, new ShardSyncedFlushRequest(shard.shardId(), syncId, expectedCommitId), new TransportResponseHandler<ShardSyncedFlushResponse>() {

            @Override
            public ShardSyncedFlushResponse newInstance() {
                return new ShardSyncedFlushResponse();
            }

            @Override
            public void handleResponse(ShardSyncedFlushResponse response) {
                ShardSyncedFlushResponse existing = results.put(shard, response);
                assert existing == null : "got two answers for node [" + node + "]";
                // count after the assert so we won't decrement twice in handleException
                contDownAndSendResponseIfDone(syncId, shards, shardId, totalShards, listener, countDown, results);
            }

            @Override
            public void handleException(TransportException exp) {
                logger.trace((Supplier<?>) () -> new ParameterizedMessage("{} error while performing synced flush on [{}], skipping", shardId, shard), exp);
                results.put(shard, new ShardSyncedFlushResponse(exp.getMessage()));
                contDownAndSendResponseIfDone(syncId, shards, shardId, totalShards, listener, countDown, results);
            }

            @Override
            public String executor() {
                return ThreadPool.Names.SAME;
            }
        });
    }
}
Also used : DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) CountDown(org.elasticsearch.common.util.concurrent.CountDown) TransportException(org.elasticsearch.transport.TransportException) Supplier(org.apache.logging.log4j.util.Supplier) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting) Engine(org.elasticsearch.index.engine.Engine)

Example 7 with CountDown

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

the class SyncedFlushService method sendPreSyncRequests.

/**
     * send presync requests to all started copies of the given shard
     */
void sendPreSyncRequests(final List<ShardRouting> shards, final ClusterState state, final ShardId shardId, final ActionListener<Map<String, Engine.CommitId>> listener) {
    final CountDown countDown = new CountDown(shards.size());
    final ConcurrentMap<String, Engine.CommitId> commitIds = ConcurrentCollections.newConcurrentMap();
    for (final ShardRouting shard : shards) {
        logger.trace("{} sending pre-synced flush request to {}", shardId, shard);
        final DiscoveryNode node = state.nodes().get(shard.currentNodeId());
        if (node == null) {
            logger.trace("{} shard routing {} refers to an unknown node. skipping.", shardId, shard);
            if (countDown.countDown()) {
                listener.onResponse(commitIds);
            }
            continue;
        }
        transportService.sendRequest(node, PRE_SYNCED_FLUSH_ACTION_NAME, new PreShardSyncedFlushRequest(shard.shardId()), new TransportResponseHandler<PreSyncedFlushResponse>() {

            @Override
            public PreSyncedFlushResponse newInstance() {
                return new PreSyncedFlushResponse();
            }

            @Override
            public void handleResponse(PreSyncedFlushResponse response) {
                Engine.CommitId existing = commitIds.putIfAbsent(node.getId(), response.commitId());
                assert existing == null : "got two answers for node [" + node + "]";
                // count after the assert so we won't decrement twice in handleException
                if (countDown.countDown()) {
                    listener.onResponse(commitIds);
                }
            }

            @Override
            public void handleException(TransportException exp) {
                logger.trace((Supplier<?>) () -> new ParameterizedMessage("{} error while performing pre synced flush on [{}], skipping", shardId, shard), exp);
                if (countDown.countDown()) {
                    listener.onResponse(commitIds);
                }
            }

            @Override
            public String executor() {
                return ThreadPool.Names.SAME;
            }
        });
    }
}
Also used : DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) CountDown(org.elasticsearch.common.util.concurrent.CountDown) TransportException(org.elasticsearch.transport.TransportException) Supplier(org.apache.logging.log4j.util.Supplier) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting)

Example 8 with CountDown

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

the class TransportBroadcastReplicationAction method doExecute.

@Override
protected void doExecute(Task task, 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(task, request, shardId, shardActionListener);
    }
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) CountDown(org.elasticsearch.common.util.concurrent.CountDown) BroadcastShardOperationFailedException(org.elasticsearch.action.support.broadcast.BroadcastShardOperationFailedException) ShardOperationFailedException(org.elasticsearch.action.ShardOperationFailedException) DefaultShardOperationFailedException(org.elasticsearch.action.support.DefaultShardOperationFailedException) ShardId(org.elasticsearch.index.shard.ShardId) ActionListener(org.elasticsearch.action.ActionListener) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList)

Example 9 with CountDown

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

the class GoogleCloudStorageBlobStore method deleteBlobs.

/**
     * Deletes multiple blobs in the given bucket (uses a batch request to perform this)
     *
     * @param blobNames names of the bucket to delete
     */
void deleteBlobs(Collection<String> blobNames) throws IOException {
    if (blobNames == null || blobNames.isEmpty()) {
        return;
    }
    if (blobNames.size() == 1) {
        deleteBlob(blobNames.iterator().next());
        return;
    }
    final List<Storage.Objects.Delete> deletions = new ArrayList<>();
    final Iterator<String> blobs = blobNames.iterator();
    SocketAccess.doPrivilegedVoidIOException(() -> {
        while (blobs.hasNext()) {
            // Create a delete request for each blob to delete
            deletions.add(client.objects().delete(bucket, blobs.next()));
            if (blobs.hasNext() == false || deletions.size() == MAX_BATCHING_REQUESTS) {
                try {
                    // Deletions are executed using a batch request
                    BatchRequest batch = client.batch();
                    // Used to track successful deletions
                    CountDown countDown = new CountDown(deletions.size());
                    for (Storage.Objects.Delete delete : deletions) {
                        // Queue the delete request in batch
                        delete.queue(batch, new JsonBatchCallback<Void>() {

                            @Override
                            public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) throws IOException {
                                logger.error("failed to delete blob [{}] in bucket [{}]: {}", delete.getObject(), delete.getBucket(), e.getMessage());
                            }

                            @Override
                            public void onSuccess(Void aVoid, HttpHeaders responseHeaders) throws IOException {
                                countDown.countDown();
                            }
                        });
                    }
                    batch.execute();
                    if (countDown.isCountedDown() == false) {
                        throw new IOException("Failed to delete all [" + deletions.size() + "] blobs");
                    }
                } finally {
                    deletions.clear();
                }
            }
        }
    });
}
Also used : BatchRequest(com.google.api.client.googleapis.batch.BatchRequest) HttpHeaders(com.google.api.client.http.HttpHeaders) ArrayList(java.util.ArrayList) IOException(java.io.IOException) CountDown(org.elasticsearch.common.util.concurrent.CountDown) Storage(com.google.api.services.storage.Storage) Objects(com.google.api.services.storage.model.Objects) GoogleJsonError(com.google.api.client.googleapis.json.GoogleJsonError)

Example 10 with CountDown

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

the class SyncedFlushService method sendSyncRequests.

void sendSyncRequests(final String syncId, final List<ShardRouting> shards, ClusterState state, Map<String, PreSyncedFlushResponse> preSyncResponses, final ShardId shardId, final int totalShards, final ActionListener<ShardsSyncedFlushResult> listener) {
    final CountDown countDown = new CountDown(shards.size());
    final Map<ShardRouting, ShardSyncedFlushResponse> results = ConcurrentCollections.newConcurrentMap();
    final int numDocsOnPrimary = numDocsOnPrimary(shards, preSyncResponses);
    for (final ShardRouting shard : shards) {
        final DiscoveryNode node = state.nodes().get(shard.currentNodeId());
        if (node == null) {
            LOGGER.trace("{} is assigned to an unknown node. skipping for sync id [{}]. shard routing {}", shardId, syncId, shard);
            results.put(shard, new ShardSyncedFlushResponse("unknown node"));
            countDownAndSendResponseIfDone(syncId, shards, shardId, totalShards, listener, countDown, results);
            continue;
        }
        final PreSyncedFlushResponse preSyncedResponse = preSyncResponses.get(shard.currentNodeId());
        if (preSyncedResponse == null) {
            LOGGER.trace("{} can't resolve expected commit id for current node, skipping for sync id [{}]. shard routing {}", shardId, syncId, shard);
            results.put(shard, new ShardSyncedFlushResponse("no commit id from pre-sync flush"));
            countDownAndSendResponseIfDone(syncId, shards, shardId, totalShards, listener, countDown, results);
            continue;
        }
        if (preSyncedResponse.numDocs != numDocsOnPrimary && preSyncedResponse.numDocs != PreSyncedFlushResponse.UNKNOWN_NUM_DOCS && numDocsOnPrimary != PreSyncedFlushResponse.UNKNOWN_NUM_DOCS) {
            LOGGER.warn("{} can't to issue sync id [{}] for out of sync replica [{}] with num docs [{}]; num docs on primary [{}]", shardId, syncId, shard, preSyncedResponse.numDocs, numDocsOnPrimary);
            results.put(shard, new ShardSyncedFlushResponse("out of sync replica; " + "num docs on replica [" + preSyncedResponse.numDocs + "]; num docs on primary [" + numDocsOnPrimary + "]"));
            countDownAndSendResponseIfDone(syncId, shards, shardId, totalShards, listener, countDown, results);
            continue;
        }
        LOGGER.trace("{} sending synced flush request to {}. sync id [{}].", shardId, shard, syncId);
        transportService.sendRequest(node, SYNCED_FLUSH_ACTION_NAME, new ShardSyncedFlushRequest(shard.shardId(), syncId, preSyncedResponse.commitId), new TransportResponseHandler<ShardSyncedFlushResponse>() {

            @Override
            public ShardSyncedFlushResponse read(StreamInput in) throws IOException {
                return new ShardSyncedFlushResponse(in);
            }

            @Override
            public void handleResponse(ShardSyncedFlushResponse response) {
                ShardSyncedFlushResponse existing = results.put(shard, response);
                assert existing == null : "got two answers for node [" + node + "]";
                // count after the assert so we won't decrement twice in handleException
                countDownAndSendResponseIfDone(syncId, shards, shardId, totalShards, listener, countDown, results);
            }

            @Override
            public void handleException(TransportException exp) {
                LOGGER.trace(() -> new ParameterizedMessage("{} error while performing synced flush on [{}], skipping", shardId, shard), exp);
                results.put(shard, new ShardSyncedFlushResponse(exp.getMessage()));
                countDownAndSendResponseIfDone(syncId, shards, shardId, totalShards, listener, countDown, results);
            }

            @Override
            public String executor() {
                return ThreadPool.Names.SAME;
            }
        });
    }
}
Also used : DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) IOException(java.io.IOException) CountDown(org.elasticsearch.common.util.concurrent.CountDown) TransportException(org.elasticsearch.transport.TransportException) StreamInput(org.elasticsearch.common.io.stream.StreamInput) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting)

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