Search in sources :

Example 36 with Future

use of java.util.concurrent.Future in project hbase by apache.

the class TestFastFail method testFastFail.

@Ignore("Can go zombie -- see HBASE-14421; FIX")
@Test
public void testFastFail() throws IOException, InterruptedException {
    Admin admin = TEST_UTIL.getAdmin();
    final String tableName = name.getMethodName();
    HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(Bytes.toBytes(tableName)));
    desc.addFamily(new HColumnDescriptor(FAMILY));
    admin.createTable(desc, Bytes.toBytes("aaaa"), Bytes.toBytes("zzzz"), 32);
    final long numRows = 1000;
    Configuration conf = TEST_UTIL.getConfiguration();
    conf.setLong(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT, SLEEPTIME * 100);
    conf.setInt(HConstants.HBASE_CLIENT_PAUSE, SLEEPTIME / 10);
    conf.setBoolean(HConstants.HBASE_CLIENT_FAST_FAIL_MODE_ENABLED, true);
    conf.setLong(HConstants.HBASE_CLIENT_FAST_FAIL_THREASHOLD_MS, 0);
    conf.setClass(HConstants.HBASE_CLIENT_FAST_FAIL_INTERCEPTOR_IMPL, MyPreemptiveFastFailInterceptor.class, PreemptiveFastFailInterceptor.class);
    final Connection connection = ConnectionFactory.createConnection(conf);
    /**
     * Write numRows worth of data, so that the workers can arbitrarily read.
     */
    List<Put> puts = new ArrayList<>();
    for (long i = 0; i < numRows; i++) {
        byte[] rowKey = longToByteArrayKey(i);
        Put put = new Put(rowKey);
        // value is the same as the row key
        byte[] value = rowKey;
        put.addColumn(FAMILY, QUALIFIER, value);
        puts.add(put);
    }
    try (Table table = connection.getTable(TableName.valueOf(tableName))) {
        table.put(puts);
        LOG.info("Written all puts.");
    }
    /**
     * The number of threads that are going to perform actions against the test
     * table.
     */
    int nThreads = 100;
    ExecutorService service = Executors.newFixedThreadPool(nThreads);
    final CountDownLatch continueOtherHalf = new CountDownLatch(1);
    final CountDownLatch doneHalfway = new CountDownLatch(nThreads);
    final AtomicInteger numSuccessfullThreads = new AtomicInteger(0);
    final AtomicInteger numFailedThreads = new AtomicInteger(0);
    // The total time taken for the threads to perform the second put;
    final AtomicLong totalTimeTaken = new AtomicLong(0);
    final AtomicInteger numBlockedWorkers = new AtomicInteger(0);
    final AtomicInteger numPreemptiveFastFailExceptions = new AtomicInteger(0);
    List<Future<Boolean>> futures = new ArrayList<>();
    for (int i = 0; i < nThreads; i++) {
        futures.add(service.submit(new Callable<Boolean>() {

            /**
         * The workers are going to perform a couple of reads. The second read
         * will follow the killing of a regionserver so that we make sure that
         * some of threads go into PreemptiveFastFailExcception
         */
            public Boolean call() throws Exception {
                try (Table table = connection.getTable(TableName.valueOf(tableName))) {
                    // Add some jitter here
                    Thread.sleep(Math.abs(random.nextInt()) % 250);
                    byte[] row = longToByteArrayKey(Math.abs(random.nextLong()) % numRows);
                    Get g = new Get(row);
                    g.addColumn(FAMILY, QUALIFIER);
                    try {
                        table.get(g);
                    } catch (Exception e) {
                        LOG.debug("Get failed : ", e);
                        doneHalfway.countDown();
                        return false;
                    }
                    // Done with one get, proceeding to do the next one.
                    doneHalfway.countDown();
                    continueOtherHalf.await();
                    long startTime = System.currentTimeMillis();
                    g = new Get(row);
                    g.addColumn(FAMILY, QUALIFIER);
                    try {
                        table.get(g);
                        // The get was successful
                        numSuccessfullThreads.addAndGet(1);
                    } catch (Exception e) {
                        if (e instanceof PreemptiveFastFailException) {
                            // We were issued a PreemptiveFastFailException
                            numPreemptiveFastFailExceptions.addAndGet(1);
                        }
                        // Irrespective of PFFE, the request failed.
                        numFailedThreads.addAndGet(1);
                        return false;
                    } finally {
                        long enTime = System.currentTimeMillis();
                        totalTimeTaken.addAndGet(enTime - startTime);
                        if ((enTime - startTime) >= SLEEPTIME) {
                            // Considering the slow workers as the blockedWorkers.
                            // This assumes that the threads go full throttle at performing
                            // actions. In case the thread scheduling itself is as slow as
                            // SLEEPTIME, then this test might fail and so, we might have
                            // set it to a higher number on slower machines.
                            numBlockedWorkers.addAndGet(1);
                        }
                    }
                    return true;
                } catch (Exception e) {
                    LOG.error("Caught unknown exception", e);
                    doneHalfway.countDown();
                    return false;
                }
            }
        }));
    }
    doneHalfway.await();
    // Kill a regionserver
    TEST_UTIL.getHBaseCluster().getRegionServer(0).getRpcServer().stop();
    TEST_UTIL.getHBaseCluster().getRegionServer(0).stop("Testing");
    // Let the threads continue going
    continueOtherHalf.countDown();
    Thread.sleep(2 * SLEEPTIME);
    // Start a RS in the cluster
    TEST_UTIL.getHBaseCluster().startRegionServer();
    int numThreadsReturnedFalse = 0;
    int numThreadsReturnedTrue = 0;
    int numThreadsThrewExceptions = 0;
    for (Future<Boolean> f : futures) {
        try {
            numThreadsReturnedTrue += f.get() ? 1 : 0;
            numThreadsReturnedFalse += f.get() ? 0 : 1;
        } catch (Exception e) {
            numThreadsThrewExceptions++;
        }
    }
    LOG.debug("numThreadsReturnedFalse:" + numThreadsReturnedFalse + " numThreadsReturnedTrue:" + numThreadsReturnedTrue + " numThreadsThrewExceptions:" + numThreadsThrewExceptions + " numFailedThreads:" + numFailedThreads.get() + " numSuccessfullThreads:" + numSuccessfullThreads.get() + " numBlockedWorkers:" + numBlockedWorkers.get() + " totalTimeWaited: " + totalTimeTaken.get() / (numBlockedWorkers.get() == 0 ? Long.MAX_VALUE : numBlockedWorkers.get()) + " numPFFEs: " + numPreemptiveFastFailExceptions.get());
    assertEquals("The expected number of all the successfull and the failed " + "threads should equal the total number of threads that we spawned", nThreads, numFailedThreads.get() + numSuccessfullThreads.get());
    assertEquals("All the failures should be coming from the secondput failure", numFailedThreads.get(), numThreadsReturnedFalse);
    assertEquals("Number of threads that threw execution exceptions " + "otherwise should be 0", numThreadsThrewExceptions, 0);
    assertEquals("The regionservers that returned true should equal to the" + " number of successful threads", numThreadsReturnedTrue, numSuccessfullThreads.get());
    assertTrue("There will be atleast one thread that retried instead of failing", MyPreemptiveFastFailInterceptor.numBraveSouls.get() > 0);
    assertTrue("There will be atleast one PreemptiveFastFail exception," + " otherwise, the test makes little sense." + "numPreemptiveFastFailExceptions: " + numPreemptiveFastFailExceptions.get(), numPreemptiveFastFailExceptions.get() > 0);
    assertTrue("Only few thread should ideally be waiting for the dead " + "regionserver to be coming back. numBlockedWorkers:" + numBlockedWorkers.get() + " threads that retried : " + MyPreemptiveFastFailInterceptor.numBraveSouls.get(), numBlockedWorkers.get() <= MyPreemptiveFastFailInterceptor.numBraveSouls.get());
}
Also used : Configuration(org.apache.hadoop.conf.Configuration) HBaseConfiguration(org.apache.hadoop.hbase.HBaseConfiguration) ArrayList(java.util.ArrayList) Callable(java.util.concurrent.Callable) HColumnDescriptor(org.apache.hadoop.hbase.HColumnDescriptor) PreemptiveFastFailException(org.apache.hadoop.hbase.exceptions.PreemptiveFastFailException) CountDownLatch(java.util.concurrent.CountDownLatch) PreemptiveFastFailException(org.apache.hadoop.hbase.exceptions.PreemptiveFastFailException) IOException(java.io.IOException) HTableDescriptor(org.apache.hadoop.hbase.HTableDescriptor) AtomicLong(java.util.concurrent.atomic.AtomicLong) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 37 with Future

use of java.util.concurrent.Future in project hive by apache.

the class TestReflectionObjectInspectors method testObjectInspectorThreadSafety.

public void testObjectInspectorThreadSafety() throws InterruptedException {
    // 5 workers to run getReflectionObjectInspector concurrently
    final int workerCount = 5;
    final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(workerCount);
    final MutableObject exception = new MutableObject();
    Thread runner = new Thread(new Runnable() {

        @Override
        @SuppressWarnings("unchecked")
        public void run() {
            Future<ObjectInspector>[] results = (Future<ObjectInspector>[]) new Future[workerCount];
            ObjectPair<Type, ObjectInspectorFactory.ObjectInspectorOptions>[] types = (ObjectPair<Type, ObjectInspectorFactory.ObjectInspectorOptions>[]) new ObjectPair[] { new ObjectPair<Type, ObjectInspectorFactory.ObjectInspectorOptions>(Complex.class, ObjectInspectorFactory.ObjectInspectorOptions.THRIFT), new ObjectPair<Type, ObjectInspectorFactory.ObjectInspectorOptions>(MyStruct.class, ObjectInspectorFactory.ObjectInspectorOptions.JAVA) };
            try {
                for (int i = 0; i < 20; i++) {
                    // repeat 20 times
                    for (final ObjectPair<Type, ObjectInspectorFactory.ObjectInspectorOptions> t : types) {
                        ObjectInspectorFactory.objectInspectorCache.clear();
                        for (int k = 0; k < workerCount; k++) {
                            results[k] = executorService.schedule(new Callable<ObjectInspector>() {

                                @Override
                                public ObjectInspector call() throws Exception {
                                    return ObjectInspectorFactory.getReflectionObjectInspector(t.getFirst(), t.getSecond());
                                }
                            }, 50, TimeUnit.MILLISECONDS);
                        }
                        ObjectInspector oi = results[0].get();
                        for (int k = 1; k < workerCount; k++) {
                            assertEquals(oi, results[k].get());
                        }
                    }
                }
            } catch (Throwable e) {
                exception.setValue(e);
            }
        }
    });
    try {
        runner.start();
        // timeout in 5 minutes
        long endTime = System.currentTimeMillis() + 300000;
        while (runner.isAlive()) {
            if (System.currentTimeMillis() > endTime) {
                // Interrupt the runner thread
                runner.interrupt();
                fail("Timed out waiting for the runner to finish");
            }
            runner.join(10000);
        }
        if (exception.getValue() != null) {
            fail("Got exception: " + exception.getValue());
        }
    } finally {
        executorService.shutdownNow();
    }
}
Also used : ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) Type(java.lang.reflect.Type) Future(java.util.concurrent.Future) PrimitiveObjectInspectorFactory(org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory) MutableObject(org.apache.commons.lang.mutable.MutableObject) ObjectPair(org.apache.hadoop.hive.common.ObjectPair)

Example 38 with Future

use of java.util.concurrent.Future in project kafka by apache.

the class RecordCollectorTest method shouldThrowStreamsExceptionOnSubsequentCallIfASendFails.

@SuppressWarnings("unchecked")
@Test(expected = StreamsException.class)
public void shouldThrowStreamsExceptionOnSubsequentCallIfASendFails() throws Exception {
    final RecordCollector collector = new RecordCollectorImpl(new MockProducer(cluster, true, new DefaultPartitioner(), byteArraySerializer, byteArraySerializer) {

        @Override
        public synchronized Future<RecordMetadata> send(final ProducerRecord record, final Callback callback) {
            callback.onCompletion(null, new Exception());
            return null;
        }
    }, "test");
    collector.send("topic1", "3", "0", null, null, stringSerializer, stringSerializer, streamPartitioner);
    collector.send("topic1", "3", "0", null, null, stringSerializer, stringSerializer, streamPartitioner);
}
Also used : MockProducer(org.apache.kafka.clients.producer.MockProducer) Callback(org.apache.kafka.clients.producer.Callback) DefaultPartitioner(org.apache.kafka.clients.producer.internals.DefaultPartitioner) ProducerRecord(org.apache.kafka.clients.producer.ProducerRecord) Future(java.util.concurrent.Future) TimeoutException(org.apache.kafka.common.errors.TimeoutException) StreamsException(org.apache.kafka.streams.errors.StreamsException) Test(org.junit.Test)

Example 39 with Future

use of java.util.concurrent.Future in project kafka by apache.

the class RecordCollectorTest method shouldThrowStreamsExceptionOnCloseIfASendFailed.

@SuppressWarnings("unchecked")
@Test(expected = StreamsException.class)
public void shouldThrowStreamsExceptionOnCloseIfASendFailed() throws Exception {
    final RecordCollector collector = new RecordCollectorImpl(new MockProducer(cluster, true, new DefaultPartitioner(), byteArraySerializer, byteArraySerializer) {

        @Override
        public synchronized Future<RecordMetadata> send(final ProducerRecord record, final Callback callback) {
            callback.onCompletion(null, new Exception());
            return null;
        }
    }, "test");
    collector.send("topic1", "3", "0", null, null, stringSerializer, stringSerializer, streamPartitioner);
    collector.close();
}
Also used : MockProducer(org.apache.kafka.clients.producer.MockProducer) Callback(org.apache.kafka.clients.producer.Callback) DefaultPartitioner(org.apache.kafka.clients.producer.internals.DefaultPartitioner) ProducerRecord(org.apache.kafka.clients.producer.ProducerRecord) Future(java.util.concurrent.Future) TimeoutException(org.apache.kafka.common.errors.TimeoutException) StreamsException(org.apache.kafka.streams.errors.StreamsException) Test(org.junit.Test)

Example 40 with Future

use of java.util.concurrent.Future in project kafka by apache.

the class WorkerSourceTaskTest method expectSendRecord.

private Capture<ProducerRecord<byte[], byte[]>> expectSendRecord(boolean anyTimes, boolean isRetry, boolean succeed) throws InterruptedException {
    expectConvertKeyValue(anyTimes);
    expectApplyTransformationChain(anyTimes);
    Capture<ProducerRecord<byte[], byte[]>> sent = EasyMock.newCapture();
    // 1. Offset data is passed to the offset storage.
    if (!isRetry) {
        offsetWriter.offset(PARTITION, OFFSET);
        if (anyTimes)
            PowerMock.expectLastCall().anyTimes();
        else
            PowerMock.expectLastCall();
    }
    // 2. Converted data passed to the producer, which will need callbacks invoked for flush to work
    IExpectationSetters<Future<RecordMetadata>> expect = EasyMock.expect(producer.send(EasyMock.capture(sent), EasyMock.capture(producerCallbacks)));
    IAnswer<Future<RecordMetadata>> expectResponse = new IAnswer<Future<RecordMetadata>>() {

        @Override
        public Future<RecordMetadata> answer() throws Throwable {
            synchronized (producerCallbacks) {
                for (org.apache.kafka.clients.producer.Callback cb : producerCallbacks.getValues()) {
                    cb.onCompletion(new RecordMetadata(new TopicPartition("foo", 0), 0, 0, 0L, 0L, 0, 0), null);
                }
                producerCallbacks.reset();
            }
            return sendFuture;
        }
    };
    if (anyTimes)
        expect.andStubAnswer(expectResponse);
    else
        expect.andAnswer(expectResponse);
    // 3. As a result of a successful producer send callback, we'll notify the source task of the record commit
    expectTaskCommitRecord(anyTimes, succeed);
    return sent;
}
Also used : RecordMetadata(org.apache.kafka.clients.producer.RecordMetadata) IAnswer(org.easymock.IAnswer) TopicPartition(org.apache.kafka.common.TopicPartition) ProducerRecord(org.apache.kafka.clients.producer.ProducerRecord) Future(java.util.concurrent.Future)

Aggregations

Future (java.util.concurrent.Future)1138 ArrayList (java.util.ArrayList)479 ExecutorService (java.util.concurrent.ExecutorService)445 Test (org.junit.Test)413 ExecutionException (java.util.concurrent.ExecutionException)264 Callable (java.util.concurrent.Callable)206 IOException (java.io.IOException)177 ParallelTest (com.hazelcast.test.annotation.ParallelTest)148 QuickTest (com.hazelcast.test.annotation.QuickTest)148 HashMap (java.util.HashMap)92 List (java.util.List)84 CountDownLatch (java.util.concurrent.CountDownLatch)71 LinkedList (java.util.LinkedList)67 TimeoutException (java.util.concurrent.TimeoutException)63 HashSet (java.util.HashSet)62 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)59 Map (java.util.Map)58 ICompletableFuture (com.hazelcast.core.ICompletableFuture)57 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)53 File (java.io.File)46