use of org.elasticsearch.common.util.concurrent.AbstractRunnable in project elasticsearch by elastic.
the class NodeJoinControllerTests method testElectionWithConcurrentJoins.
public void testElectionWithConcurrentJoins() throws InterruptedException, BrokenBarrierException {
DiscoveryNodes.Builder nodesBuilder = DiscoveryNodes.builder(clusterService.state().nodes()).masterNodeId(null);
setState(clusterService, ClusterState.builder(clusterService.state()).nodes(nodesBuilder));
nodeJoinController.startElectionContext();
Thread[] threads = new Thread[3 + randomInt(5)];
final int requiredJoins = randomInt(threads.length);
ArrayList<DiscoveryNode> nodes = new ArrayList<>();
nodes.add(clusterService.localNode());
final CyclicBarrier barrier = new CyclicBarrier(threads.length + 1);
final List<Throwable> backgroundExceptions = new CopyOnWriteArrayList<>();
for (int i = 0; i < threads.length; i++) {
final DiscoveryNode node = newNode(i, true);
final int iterations = rarely() ? randomIntBetween(1, 4) : 1;
nodes.add(node);
threads[i] = new Thread(new AbstractRunnable() {
@Override
public void onFailure(Exception e) {
logger.error("unexpected error in join thread", e);
backgroundExceptions.add(e);
}
@Override
protected void doRun() throws Exception {
barrier.await();
for (int i = 0; i < iterations; i++) {
logger.debug("{} joining", node);
joinNode(node);
}
}
}, "t_" + i);
threads[i].start();
}
barrier.await();
logger.info("--> waiting to be elected as master (required joins [{}])", requiredJoins);
final AtomicReference<Throwable> failure = new AtomicReference<>();
final CountDownLatch latch = new CountDownLatch(1);
nodeJoinController.waitToBeElectedAsMaster(requiredJoins, TimeValue.timeValueHours(30), new NodeJoinController.ElectionCallback() {
@Override
public void onElectedAsMaster(ClusterState state) {
assertThat("callback called with elected as master, but state disagrees", state.nodes().isLocalNodeElectedMaster(), equalTo(true));
latch.countDown();
}
@Override
public void onFailure(Throwable t) {
logger.error("unexpected error while waiting to be elected as master", t);
failure.set(t);
latch.countDown();
}
});
latch.await();
ExceptionsHelper.reThrowIfNotNull(failure.get());
logger.info("--> waiting for joins to complete");
for (Thread thread : threads) {
thread.join();
}
assertNodesInCurrentState(nodes);
}
use of org.elasticsearch.common.util.concurrent.AbstractRunnable in project elasticsearch by elastic.
the class NodeEnvironmentTests method testDeleteSafe.
public void testDeleteSafe() throws Exception {
final NodeEnvironment env = newNodeEnvironment();
final Index index = new Index("foo", "fooUUID");
ShardLock fooLock = env.shardLock(new ShardId(index, 0));
assertEquals(new ShardId(index, 0), fooLock.getShardId());
for (Path path : env.indexPaths(index)) {
Files.createDirectories(path.resolve("0"));
Files.createDirectories(path.resolve("1"));
}
try {
env.deleteShardDirectorySafe(new ShardId(index, 0), idxSettings);
fail("shard is locked");
} catch (ShardLockObtainFailedException ex) {
// expected
}
for (Path path : env.indexPaths(index)) {
assertTrue(Files.exists(path.resolve("0")));
assertTrue(Files.exists(path.resolve("1")));
}
env.deleteShardDirectorySafe(new ShardId(index, 1), idxSettings);
for (Path path : env.indexPaths(index)) {
assertTrue(Files.exists(path.resolve("0")));
assertFalse(Files.exists(path.resolve("1")));
}
try {
env.deleteIndexDirectorySafe(index, randomIntBetween(0, 10), idxSettings);
fail("shard is locked");
} catch (ShardLockObtainFailedException ex) {
// expected
}
fooLock.close();
for (Path path : env.indexPaths(index)) {
assertTrue(Files.exists(path));
}
final AtomicReference<Throwable> threadException = new AtomicReference<>();
final CountDownLatch latch = new CountDownLatch(1);
final CountDownLatch blockLatch = new CountDownLatch(1);
final CountDownLatch start = new CountDownLatch(1);
if (randomBoolean()) {
Thread t = new Thread(new AbstractRunnable() {
@Override
public void onFailure(Exception e) {
logger.error("unexpected error", e);
threadException.set(e);
latch.countDown();
blockLatch.countDown();
}
@Override
protected void doRun() throws Exception {
start.await();
try (ShardLock autoCloses = env.shardLock(new ShardId(index, 0))) {
blockLatch.countDown();
Thread.sleep(randomIntBetween(1, 10));
}
latch.countDown();
}
});
t.start();
} else {
latch.countDown();
blockLatch.countDown();
}
start.countDown();
blockLatch.await();
env.deleteIndexDirectorySafe(index, 5000, idxSettings);
assertNull(threadException.get());
for (Path path : env.indexPaths(index)) {
assertFalse(Files.exists(path));
}
latch.await();
assertTrue("LockedShards: " + env.lockedShards(), env.lockedShards().isEmpty());
env.close();
}
use of org.elasticsearch.common.util.concurrent.AbstractRunnable in project elasticsearch by elastic.
the class LocalCheckpointTrackerTests method testConcurrentPrimary.
public void testConcurrentPrimary() throws InterruptedException {
Thread[] threads = new Thread[randomIntBetween(2, 5)];
final int opsPerThread = randomIntBetween(10, 20);
final int maxOps = opsPerThread * threads.length;
// make sure we always index the last seqNo to simplify maxSeq checks
final long unFinishedSeq = randomIntBetween(0, maxOps - 2);
logger.info("--> will run [{}] threads, maxOps [{}], unfinished seq no [{}]", threads.length, maxOps, unFinishedSeq);
final CyclicBarrier barrier = new CyclicBarrier(threads.length);
for (int t = 0; t < threads.length; t++) {
final int threadId = t;
threads[t] = new Thread(new AbstractRunnable() {
@Override
public void onFailure(Exception e) {
throw new ElasticsearchException("failure in background thread", e);
}
@Override
protected void doRun() throws Exception {
barrier.await();
for (int i = 0; i < opsPerThread; i++) {
long seqNo = tracker.generateSeqNo();
logger.info("[t{}] started [{}]", threadId, seqNo);
if (seqNo != unFinishedSeq) {
tracker.markSeqNoAsCompleted(seqNo);
logger.info("[t{}] completed [{}]", threadId, seqNo);
}
}
}
}, "testConcurrentPrimary_" + threadId);
threads[t].start();
}
for (Thread thread : threads) {
thread.join();
}
assertThat(tracker.getMaxSeqNo(), equalTo(maxOps - 1L));
assertThat(tracker.getCheckpoint(), equalTo(unFinishedSeq - 1L));
tracker.markSeqNoAsCompleted(unFinishedSeq);
assertThat(tracker.getCheckpoint(), equalTo(maxOps - 1L));
assertThat(tracker.processedSeqNo.size(), isOneOf(0, 1));
assertThat(tracker.firstProcessedSeqNo, equalTo(((long) maxOps / SMALL_CHUNK_SIZE) * SMALL_CHUNK_SIZE));
}
use of org.elasticsearch.common.util.concurrent.AbstractRunnable in project elasticsearch by elastic.
the class PipelineExecutionService method executeIndexRequest.
public void executeIndexRequest(IndexRequest request, Consumer<Exception> failureHandler, Consumer<Boolean> completionHandler) {
Pipeline pipeline = getPipeline(request.getPipeline());
threadPool.executor(ThreadPool.Names.INDEX).execute(new AbstractRunnable() {
@Override
public void onFailure(Exception e) {
failureHandler.accept(e);
}
@Override
protected void doRun() throws Exception {
innerExecute(request, pipeline);
completionHandler.accept(true);
}
});
}
use of org.elasticsearch.common.util.concurrent.AbstractRunnable in project elasticsearch by elastic.
the class TransportGetTaskAction method getRunningTaskFromNode.
/**
* Executed on the node that should be running the task to find and return the running task. Falls back to
* {@link #getFinishedTaskFromIndex(Task, GetTaskRequest, ActionListener)} if the task isn't still running.
*/
void getRunningTaskFromNode(Task thisTask, GetTaskRequest request, ActionListener<GetTaskResponse> listener) {
Task runningTask = taskManager.getTask(request.getTaskId().getId());
if (runningTask == null) {
// Task isn't running, go look in the task index
getFinishedTaskFromIndex(thisTask, request, listener);
} else {
if (request.getWaitForCompletion()) {
// Shift to the generic thread pool and let it wait for the task to complete so we don't block any important threads.
threadPool.generic().execute(new AbstractRunnable() {
@Override
protected void doRun() throws Exception {
taskManager.waitForTaskCompletion(runningTask, waitForCompletionTimeout(request.getTimeout()));
waitedForCompletion(thisTask, request, runningTask.taskInfo(clusterService.localNode().getId(), true), listener);
}
@Override
public void onFailure(Exception e) {
listener.onFailure(e);
}
});
} else {
TaskInfo info = runningTask.taskInfo(clusterService.localNode().getId(), true);
listener.onResponse(new GetTaskResponse(new TaskResult(false, info)));
}
}
}
Aggregations