Search in sources :

Example 1 with Cancellable

use of org.elasticsearch.threadpool.ThreadPool.Cancellable in project elasticsearch by elastic.

the class ScheduleWithFixedDelayTests method testBlockingCallOnSchedulerThreadFails.

public void testBlockingCallOnSchedulerThreadFails() throws Exception {
    final BaseFuture<Object> future = new BaseFuture<Object>() {
    };
    final TestFuture resultsFuture = new TestFuture();
    final boolean getWithTimeout = randomBoolean();
    final Runnable runnable = () -> {
        try {
            Object obj;
            if (getWithTimeout) {
                obj = future.get(1L, TimeUnit.SECONDS);
            } else {
                obj = future.get();
            }
            resultsFuture.futureDone(obj);
        } catch (Throwable t) {
            resultsFuture.futureDone(t);
        }
    };
    Cancellable cancellable = threadPool.scheduleWithFixedDelay(runnable, TimeValue.timeValueMillis(10L), Names.SAME);
    Object resultingObject = resultsFuture.get();
    assertNotNull(resultingObject);
    assertThat(resultingObject, instanceOf(Throwable.class));
    Throwable t = (Throwable) resultingObject;
    assertThat(t, instanceOf(AssertionError.class));
    assertThat(t.getMessage(), containsString("Blocking"));
    assertFalse(cancellable.isCancelled());
}
Also used : BaseFuture(org.elasticsearch.common.util.concurrent.BaseFuture) Cancellable(org.elasticsearch.threadpool.ThreadPool.Cancellable) ReschedulingRunnable(org.elasticsearch.threadpool.ThreadPool.ReschedulingRunnable)

Example 2 with Cancellable

use of org.elasticsearch.threadpool.ThreadPool.Cancellable in project elasticsearch by elastic.

the class ScheduleWithFixedDelayTests method testBlockingCallOnNonSchedulerThreadAllowed.

public void testBlockingCallOnNonSchedulerThreadAllowed() throws Exception {
    final TestFuture future = new TestFuture();
    final TestFuture resultsFuture = new TestFuture();
    final boolean rethrow = randomBoolean();
    final boolean getWithTimeout = randomBoolean();
    final Runnable runnable = () -> {
        try {
            Object obj;
            if (getWithTimeout) {
                obj = future.get(1, TimeUnit.MINUTES);
            } else {
                obj = future.get();
            }
            resultsFuture.futureDone(obj);
        } catch (Throwable t) {
            resultsFuture.futureDone(t);
            if (rethrow) {
                throw new RuntimeException(t);
            }
        }
    };
    final Cancellable cancellable = threadPool.scheduleWithFixedDelay(runnable, TimeValue.timeValueMillis(10L), Names.GENERIC);
    assertFalse(resultsFuture.isDone());
    final Object o = new Object();
    future.futureDone(o);
    final Object resultingObject = resultsFuture.get();
    assertThat(resultingObject, sameInstance(o));
    assertFalse(cancellable.isCancelled());
}
Also used : Cancellable(org.elasticsearch.threadpool.ThreadPool.Cancellable) ReschedulingRunnable(org.elasticsearch.threadpool.ThreadPool.ReschedulingRunnable)

Example 3 with Cancellable

use of org.elasticsearch.threadpool.ThreadPool.Cancellable in project elasticsearch by elastic.

the class JvmGcMonitorServiceSettingsTests method execute.

private static void execute(Settings settings, TriFunction<Runnable, TimeValue, String, Cancellable> scheduler, Consumer<Throwable> consumer, boolean constructionShouldFail, Runnable asserts) throws InterruptedException {
    assert constructionShouldFail == (consumer != null);
    assert constructionShouldFail == (asserts == null);
    ThreadPool threadPool = null;
    try {
        threadPool = new TestThreadPool(JvmGcMonitorServiceSettingsTests.class.getCanonicalName()) {

            @Override
            public Cancellable scheduleWithFixedDelay(Runnable command, TimeValue interval, String name) {
                return scheduler.apply(command, interval, name);
            }
        };
        try {
            JvmGcMonitorService service = new JvmGcMonitorService(settings, threadPool);
            if (constructionShouldFail) {
                fail("construction of jvm gc service should have failed");
            }
            service.doStart();
            asserts.run();
            service.doStop();
        } catch (Exception t) {
            consumer.accept(t);
        }
    } finally {
        ThreadPool.terminate(threadPool, 30, TimeUnit.SECONDS);
    }
}
Also used : Cancellable(org.elasticsearch.threadpool.ThreadPool.Cancellable) TestThreadPool(org.elasticsearch.threadpool.TestThreadPool) ThreadPool(org.elasticsearch.threadpool.ThreadPool) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) TestThreadPool(org.elasticsearch.threadpool.TestThreadPool) TimeValue(org.elasticsearch.common.unit.TimeValue)

Example 4 with Cancellable

use of org.elasticsearch.threadpool.ThreadPool.Cancellable in project elasticsearch by elastic.

the class RefreshListenersTests method testLotsOfThreads.

/**
     * Uses a bunch of threads to index, wait for refresh, and non-realtime get documents to validate that they are visible after waiting
     * regardless of what crazy sequence of events causes the refresh listener to fire.
     */
public void testLotsOfThreads() throws Exception {
    int threadCount = between(3, 10);
    maxListeners = between(1, threadCount * 2);
    // This thread just refreshes every once in a while to cause trouble.
    Cancellable refresher = threadPool.scheduleWithFixedDelay(() -> engine.refresh("because test"), timeValueMillis(100), Names.SAME);
    // These threads add and block until the refresh makes the change visible and then do a non-realtime get.
    Thread[] indexers = new Thread[threadCount];
    for (int thread = 0; thread < threadCount; thread++) {
        final String threadId = String.format(Locale.ROOT, "%04d", thread);
        indexers[thread] = new Thread(() -> {
            for (int iteration = 1; iteration <= 50; iteration++) {
                try {
                    String testFieldValue = String.format(Locale.ROOT, "%s%04d", threadId, iteration);
                    Engine.IndexResult index = index(threadId, testFieldValue);
                    assertEquals(iteration, index.getVersion());
                    DummyRefreshListener listener = new DummyRefreshListener();
                    listeners.addOrNotify(index.getTranslogLocation(), listener);
                    assertBusy(() -> assertNotNull("listener never called", listener.forcedRefresh.get()));
                    if (threadCount < maxListeners) {
                        assertFalse(listener.forcedRefresh.get());
                    }
                    listener.assertNoError();
                    Engine.Get get = new Engine.Get(false, new Term("_uid", Uid.createUid("test", threadId)));
                    try (Engine.GetResult getResult = engine.get(get)) {
                        assertTrue("document not found", getResult.exists());
                        assertEquals(iteration, getResult.version());
                        SingleFieldsVisitor visitor = new SingleFieldsVisitor("test");
                        getResult.docIdAndVersion().context.reader().document(getResult.docIdAndVersion().docId, visitor);
                        assertEquals(Arrays.asList(testFieldValue), visitor.fields().get("test"));
                    }
                } catch (Exception t) {
                    throw new RuntimeException("failure on the [" + iteration + "] iteration of thread [" + threadId + "]", t);
                }
            }
        });
        indexers[thread].start();
    }
    for (Thread indexer : indexers) {
        indexer.join();
    }
    refresher.cancel();
}
Also used : Cancellable(org.elasticsearch.threadpool.ThreadPool.Cancellable) Term(org.apache.lucene.index.Term) SingleFieldsVisitor(org.elasticsearch.index.fieldvisitor.SingleFieldsVisitor) IOException(java.io.IOException) Engine(org.elasticsearch.index.engine.Engine) InternalEngine(org.elasticsearch.index.engine.InternalEngine)

Example 5 with Cancellable

use of org.elasticsearch.threadpool.ThreadPool.Cancellable in project elasticsearch by elastic.

the class ScheduleWithFixedDelayTests method testCancellingRunnable.

public void testCancellingRunnable() throws Exception {
    final boolean shouldThrow = randomBoolean();
    final AtomicInteger counter = new AtomicInteger(scaledRandomIntBetween(2, 16));
    final CountDownLatch doneLatch = new CountDownLatch(1);
    final AtomicReference<Cancellable> cancellableRef = new AtomicReference<>();
    final AtomicBoolean runAfterDone = new AtomicBoolean(false);
    final Runnable countingRunnable = () -> {
        if (doneLatch.getCount() == 0) {
            runAfterDone.set(true);
            logger.warn("this runnable ran after it was cancelled");
        }
        final Cancellable cancellable = cancellableRef.get();
        if (cancellable == null) {
            // wait for the cancellable to be present before we really start so we can accurately know we cancelled
            return;
        }
        // rarely throw an exception before counting down
        if (shouldThrow && rarely()) {
            throw new RuntimeException("throw before count down");
        }
        final int count = counter.decrementAndGet();
        // see if we have counted down to zero or below yet. the exception throwing could make us count below zero
        if (count <= 0) {
            cancellable.cancel();
            doneLatch.countDown();
        }
        // rarely throw an exception after execution
        if (shouldThrow && rarely()) {
            throw new RuntimeException("throw at end");
        }
    };
    Cancellable cancellable = threadPool.scheduleWithFixedDelay(countingRunnable, TimeValue.timeValueMillis(10L), Names.GENERIC);
    cancellableRef.set(cancellable);
    // wait for the runnable to finish
    doneLatch.await();
    // the runnable should have cancelled itself
    assertTrue(cancellable.isCancelled());
    assertFalse(runAfterDone.get());
    // rarely wait and make sure the runnable didn't run at the next interval
    if (rarely()) {
        assertFalse(awaitBusy(runAfterDone::get, 1L, TimeUnit.SECONDS));
    }
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Cancellable(org.elasticsearch.threadpool.ThreadPool.Cancellable) ReschedulingRunnable(org.elasticsearch.threadpool.ThreadPool.ReschedulingRunnable) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch)

Aggregations

Cancellable (org.elasticsearch.threadpool.ThreadPool.Cancellable)7 ReschedulingRunnable (org.elasticsearch.threadpool.ThreadPool.ReschedulingRunnable)5 CountDownLatch (java.util.concurrent.CountDownLatch)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 IOException (java.io.IOException)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Term (org.apache.lucene.index.Term)1 ElasticsearchException (org.elasticsearch.ElasticsearchException)1 TimeValue (org.elasticsearch.common.unit.TimeValue)1 BaseFuture (org.elasticsearch.common.util.concurrent.BaseFuture)1 Engine (org.elasticsearch.index.engine.Engine)1 InternalEngine (org.elasticsearch.index.engine.InternalEngine)1 SingleFieldsVisitor (org.elasticsearch.index.fieldvisitor.SingleFieldsVisitor)1 TestThreadPool (org.elasticsearch.threadpool.TestThreadPool)1 ThreadPool (org.elasticsearch.threadpool.ThreadPool)1 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)1