use of java.util.concurrent.atomic.AtomicInteger in project elasticsearch by elastic.
the class TransportBulkAction method doExecute.
@Override
protected void doExecute(Task task, BulkRequest bulkRequest, ActionListener<BulkResponse> listener) {
if (bulkRequest.hasIndexRequestsWithPipelines()) {
if (clusterService.localNode().isIngestNode()) {
processBulkIndexIngestRequest(task, bulkRequest, listener);
} else {
ingestForwarder.forwardIngestRequest(BulkAction.INSTANCE, bulkRequest, listener);
}
return;
}
final long startTime = relativeTime();
final AtomicArray<BulkItemResponse> responses = new AtomicArray<>(bulkRequest.requests.size());
if (needToCheck()) {
// Keep track of all unique indices and all unique types per index for the create index requests:
final Set<String> autoCreateIndices = bulkRequest.requests.stream().map(DocWriteRequest::index).collect(Collectors.toSet());
final AtomicInteger counter = new AtomicInteger(autoCreateIndices.size());
ClusterState state = clusterService.state();
for (String index : autoCreateIndices) {
if (shouldAutoCreate(index, state)) {
CreateIndexRequest createIndexRequest = new CreateIndexRequest();
createIndexRequest.index(index);
createIndexRequest.cause("auto(bulk api)");
createIndexRequest.masterNodeTimeout(bulkRequest.timeout());
createIndexAction.execute(createIndexRequest, new ActionListener<CreateIndexResponse>() {
@Override
public void onResponse(CreateIndexResponse result) {
if (counter.decrementAndGet() == 0) {
executeBulk(task, bulkRequest, startTime, listener, responses);
}
}
@Override
public void onFailure(Exception e) {
if (!(ExceptionsHelper.unwrapCause(e) instanceof ResourceAlreadyExistsException)) {
// fail all requests involving this index, if create didnt work
for (int i = 0; i < bulkRequest.requests.size(); i++) {
DocWriteRequest request = bulkRequest.requests.get(i);
if (request != null && setResponseFailureIfIndexMatches(responses, i, request, index, e)) {
bulkRequest.requests.set(i, null);
}
}
}
if (counter.decrementAndGet() == 0) {
executeBulk(task, bulkRequest, startTime, ActionListener.wrap(listener::onResponse, inner -> {
inner.addSuppressed(e);
listener.onFailure(inner);
}), responses);
}
}
});
} else {
if (counter.decrementAndGet() == 0) {
executeBulk(task, bulkRequest, startTime, listener, responses);
}
}
}
} else {
executeBulk(task, bulkRequest, startTime, listener, responses);
}
}
use of java.util.concurrent.atomic.AtomicInteger in project elasticsearch by elastic.
the class MetaDataCreateIndexService method validateShrinkIndex.
/**
* Validates the settings and mappings for shrinking an index.
* @return the list of nodes at least one instance of the source index shards are allocated
*/
static List<String> validateShrinkIndex(ClusterState state, String sourceIndex, Set<String> targetIndexMappingsTypes, String targetIndexName, Settings targetIndexSettings) {
if (state.metaData().hasIndex(targetIndexName)) {
throw new ResourceAlreadyExistsException(state.metaData().index(targetIndexName).getIndex());
}
final IndexMetaData sourceMetaData = state.metaData().index(sourceIndex);
if (sourceMetaData == null) {
throw new IndexNotFoundException(sourceIndex);
}
// ensure index is read-only
if (state.blocks().indexBlocked(ClusterBlockLevel.WRITE, sourceIndex) == false) {
throw new IllegalStateException("index " + sourceIndex + " must be read-only to shrink index. use \"index.blocks.write=true\"");
}
if (sourceMetaData.getNumberOfShards() == 1) {
throw new IllegalArgumentException("can't shrink an index with only one shard");
}
if ((targetIndexMappingsTypes.size() > 1 || (targetIndexMappingsTypes.isEmpty() || targetIndexMappingsTypes.contains(MapperService.DEFAULT_MAPPING)) == false)) {
throw new IllegalArgumentException("mappings are not allowed when shrinking indices" + ", all mappings are copied from the source index");
}
if (IndexMetaData.INDEX_NUMBER_OF_SHARDS_SETTING.exists(targetIndexSettings)) {
// this method applies all necessary checks ie. if the target shards are less than the source shards
// of if the source shards are divisible by the number of target shards
IndexMetaData.getRoutingFactor(sourceMetaData, IndexMetaData.INDEX_NUMBER_OF_SHARDS_SETTING.get(targetIndexSettings));
}
// now check that index is all on one node
final IndexRoutingTable table = state.routingTable().index(sourceIndex);
Map<String, AtomicInteger> nodesToNumRouting = new HashMap<>();
int numShards = sourceMetaData.getNumberOfShards();
for (ShardRouting routing : table.shardsWithState(ShardRoutingState.STARTED)) {
nodesToNumRouting.computeIfAbsent(routing.currentNodeId(), (s) -> new AtomicInteger(0)).incrementAndGet();
}
List<String> nodesToAllocateOn = new ArrayList<>();
for (Map.Entry<String, AtomicInteger> entries : nodesToNumRouting.entrySet()) {
int numAllocations = entries.getValue().get();
assert numAllocations <= numShards : "wait what? " + numAllocations + " is > than num shards " + numShards;
if (numAllocations == numShards) {
nodesToAllocateOn.add(entries.getKey());
}
}
if (nodesToAllocateOn.isEmpty()) {
throw new IllegalStateException("index " + sourceIndex + " must have all shards allocated on the same node to shrink index");
}
return nodesToAllocateOn;
}
use of java.util.concurrent.atomic.AtomicInteger in project elasticsearch by elastic.
the class ActionListenerTests method testOnResponse.
public void testOnResponse() {
final int numListeners = randomIntBetween(1, 20);
List<AtomicReference<Boolean>> refList = new ArrayList<>();
List<AtomicReference<Exception>> excList = new ArrayList<>();
List<ActionListener<Boolean>> listeners = new ArrayList<>();
List<Boolean> failOnTrue = new ArrayList<>();
AtomicInteger exceptionCounter = new AtomicInteger(0);
for (int i = 0; i < numListeners; i++) {
boolean doFailOnTrue = rarely();
failOnTrue.add(doFailOnTrue);
AtomicReference<Boolean> reference = new AtomicReference<>();
AtomicReference<Exception> exReference = new AtomicReference<>();
refList.add(reference);
excList.add(exReference);
CheckedConsumer<Boolean, ? extends Exception> handler = (o) -> {
if (Boolean.FALSE.equals(o)) {
throw new IllegalArgumentException("must not be false " + exceptionCounter.getAndIncrement());
}
if (doFailOnTrue) {
throw new IllegalStateException("must not be true");
}
reference.set(o);
};
listeners.add(ActionListener.wrap(handler, exReference::set));
}
ActionListener.onResponse(listeners, Boolean.TRUE);
for (int i = 0; i < numListeners; i++) {
if (failOnTrue.get(i) == false) {
assertTrue("listener index " + i, refList.get(i).get());
refList.get(i).set(null);
} else {
assertNull("listener index " + i, refList.get(i).get());
}
}
for (int i = 0; i < numListeners; i++) {
if (failOnTrue.get(i) == false) {
assertNull("listener index " + i, excList.get(i).get());
} else {
assertEquals("listener index " + i, "must not be true", excList.get(i).get().getMessage());
}
}
ActionListener.onResponse(listeners, Boolean.FALSE);
for (int i = 0; i < numListeners; i++) {
assertNull("listener index " + i, refList.get(i).get());
}
assertEquals(numListeners, exceptionCounter.get());
for (int i = 0; i < numListeners; i++) {
assertNotNull(excList.get(i).get());
assertEquals("listener index " + i, "must not be false " + i, excList.get(i).get().getMessage());
}
}
use of java.util.concurrent.atomic.AtomicInteger in project elasticsearch by elastic.
the class BackoffPolicyTests method testWrapBackoffPolicy.
public void testWrapBackoffPolicy() {
TimeValue timeValue = timeValueMillis(between(0, Integer.MAX_VALUE));
int maxNumberOfRetries = between(1, 1000);
BackoffPolicy policy = BackoffPolicy.constantBackoff(timeValue, maxNumberOfRetries);
AtomicInteger retries = new AtomicInteger();
policy = BackoffPolicy.wrap(policy, retries::getAndIncrement);
int expectedRetries = 0;
{
// Fetching the iterator doesn't call the callback
Iterator<TimeValue> itr = policy.iterator();
assertEquals(expectedRetries, retries.get());
while (itr.hasNext()) {
// hasNext doesn't trigger the callback
assertEquals(expectedRetries, retries.get());
// next does
itr.next();
expectedRetries += 1;
assertEquals(expectedRetries, retries.get());
}
// next doesn't call the callback when there isn't a backoff available
expectThrows(NoSuchElementException.class, () -> itr.next());
assertEquals(expectedRetries, retries.get());
}
{
// The second iterator also calls the callback
Iterator<TimeValue> itr = policy.iterator();
itr.next();
expectedRetries += 1;
assertEquals(expectedRetries, retries.get());
}
}
use of java.util.concurrent.atomic.AtomicInteger in project elasticsearch by elastic.
the class TransportClientNodesServiceTests method testListenerFailures.
public void testListenerFailures() throws InterruptedException {
int iters = iterations(10, 100);
for (int i = 0; i < iters; i++) {
try (TestIteration iteration = new TestIteration()) {
// stop transport from responding early
iteration.transport.endConnectMode();
final CountDownLatch latch = new CountDownLatch(1);
final AtomicInteger finalFailures = new AtomicInteger();
final AtomicReference<Throwable> finalFailure = new AtomicReference<>();
final AtomicReference<TestResponse> response = new AtomicReference<>();
ActionListener<TestResponse> actionListener = new ActionListener<TestResponse>() {
@Override
public void onResponse(TestResponse testResponse) {
response.set(testResponse);
latch.countDown();
}
@Override
public void onFailure(Exception e) {
finalFailures.incrementAndGet();
finalFailure.set(e);
latch.countDown();
}
};
final AtomicInteger preSendFailures = new AtomicInteger();
iteration.transportClientNodesService.execute((node, retryListener) -> {
if (rarely()) {
preSendFailures.incrementAndGet();
//throw whatever exception that is not a subclass of ConnectTransportException
throw new IllegalArgumentException();
}
iteration.transportService.sendRequest(node, "action", new TestRequest(), TransportRequestOptions.EMPTY, new TransportResponseHandler<TestResponse>() {
@Override
public TestResponse newInstance() {
return new TestResponse();
}
@Override
public void handleResponse(TestResponse response1) {
retryListener.onResponse(response1);
}
@Override
public void handleException(TransportException exp) {
retryListener.onFailure(exp);
}
@Override
public String executor() {
return randomBoolean() ? ThreadPool.Names.SAME : ThreadPool.Names.GENERIC;
}
});
}, actionListener);
assertThat(latch.await(1, TimeUnit.SECONDS), equalTo(true));
//there can be only either one failure that causes the request to fail straightaway or success
assertThat(preSendFailures.get() + iteration.transport.failures() + iteration.transport.successes(), lessThanOrEqualTo(1));
if (iteration.transport.successes() == 1) {
assertThat(finalFailures.get(), equalTo(0));
assertThat(finalFailure.get(), nullValue());
assertThat(response.get(), notNullValue());
} else {
assertThat(finalFailures.get(), equalTo(1));
assertThat(finalFailure.get(), notNullValue());
assertThat(response.get(), nullValue());
if (preSendFailures.get() == 0 && iteration.transport.failures() == 0) {
assertThat(finalFailure.get(), instanceOf(NoNodeAvailableException.class));
}
}
assertThat(iteration.transport.triedNodes().size(), lessThanOrEqualTo(iteration.listNodesCount));
assertThat(iteration.transport.triedNodes().size(), equalTo(iteration.transport.connectTransportExceptions() + iteration.transport.failures() + iteration.transport.successes()));
}
}
}
Aggregations