private void innerExecute( final IndexRequest request, final ActionListener<IndexResponse> listener) { super.doExecute(request, listener); }
@Override protected void doExecute(final Request request, final ActionListener<Response> listener) { ClusterState clusterState = clusterService.state(); ClusterBlockException blockException = checkGlobalBlock(clusterState, request); if (blockException != null) { throw blockException; } // update to concrete index request.index( clusterState.metaData().concreteSingleIndex(request.index(), request.indicesOptions())); blockException = checkRequestBlock(clusterState, request); if (blockException != null) { throw blockException; } GroupShardsIterator groups; try { groups = shards(request); } catch (Throwable e) { listener.onFailure(e); return; } final AtomicInteger indexCounter = new AtomicInteger(); final AtomicInteger failureCounter = new AtomicInteger(); final AtomicInteger completionCounter = new AtomicInteger(groups.size()); final AtomicReferenceArray<ShardActionResult> shardsResponses = new AtomicReferenceArray<>(groups.size()); for (final ShardIterator shardIt : groups) { ShardRequest shardRequest = newShardRequestInstance(request, shardIt.shardId().id()); // TODO for now, we fork operations on shardIt of the index shardRequest.beforeLocalFork(); // optimize for local fork shardRequest.operationThreaded(true); // no need for threaded listener, we will fork when its done based on the index request shardRequest.listenerThreaded(false); shardAction.execute( shardRequest, new ActionListener<ShardResponse>() { @Override public void onResponse(ShardResponse result) { shardsResponses.set(indexCounter.getAndIncrement(), new ShardActionResult(result)); returnIfNeeded(); } @Override public void onFailure(Throwable e) { failureCounter.getAndIncrement(); int index = indexCounter.getAndIncrement(); if (accumulateExceptions()) { shardsResponses.set( index, new ShardActionResult( new DefaultShardOperationFailedException( request.index, shardIt.shardId().id(), e))); } returnIfNeeded(); } private void returnIfNeeded() { if (completionCounter.decrementAndGet() == 0) { List<ShardResponse> responses = Lists.newArrayList(); List<ShardOperationFailedException> failures = Lists.newArrayList(); for (int i = 0; i < shardsResponses.length(); i++) { ShardActionResult shardActionResult = shardsResponses.get(i); if (shardActionResult == null) { assert !accumulateExceptions(); continue; } if (shardActionResult.isFailure()) { assert accumulateExceptions() && shardActionResult.shardFailure != null; failures.add(shardActionResult.shardFailure); } else { responses.add(shardActionResult.shardResponse); } } assert failures.size() == 0 || failures.size() == failureCounter.get(); listener.onResponse( newResponseInstance(request, responses, failureCounter.get(), failures)); } } }); } }