Search in sources :

Example 6 with LabeledIntList

use of com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList in project gax-java by googleapis.

the class BatcherImplTest method testClosedBatchersAreNotLogged.

/**
 * Validates the absence of warning in case {@link BatcherImpl} is garbage collected after being
 * closed.
 *
 * <p>Note:This test cannot run concurrently with other tests that use Batchers.
 */
@Test
public void testClosedBatchersAreNotLogged() throws Exception {
    // Clean out the existing instances
    final long DELAY_TIME = 30L;
    int actualRemaining = 0;
    for (int retry = 0; retry < 3; retry++) {
        System.gc();
        System.runFinalization();
        actualRemaining = BatcherReference.cleanQueue();
        if (actualRemaining == 0) {
            break;
        }
        Thread.sleep(DELAY_TIME * (1L << retry));
    }
    assertThat(actualRemaining).isAtMost(0);
    // Capture logs
    final List<LogRecord> records = new ArrayList<>(1);
    Logger batcherLogger = Logger.getLogger(BatcherImpl.class.getName());
    Filter oldFilter = batcherLogger.getFilter();
    batcherLogger.setFilter(new Filter() {

        @Override
        public boolean isLoggable(LogRecord record) {
            synchronized (records) {
                records.add(record);
            }
            return false;
        }
    });
    try {
        // Create a bunch of batchers that will garbage collected after being closed
        for (int i = 0; i < 1_000; i++) {
            BatcherImpl<Integer, Integer, LabeledIntList, List<Integer>> batcher = createDefaultBatcherImpl(batchingSettings, null);
            batcher.add(1);
            if (i % 2 == 0) {
                batcher.close();
            } else {
                batcher.closeAsync();
            }
        }
        // Run GC a few times to give the batchers a chance to be collected
        for (int retry = 0; retry < 100; retry++) {
            System.gc();
            System.runFinalization();
            BatcherReference.cleanQueue();
            Thread.sleep(10);
        }
        synchronized (records) {
            assertThat(records).isEmpty();
        }
    } finally {
        // reset logging
        batcherLogger.setFilter(oldFilter);
    }
}
Also used : ArrayList(java.util.ArrayList) Logger(java.util.logging.Logger) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) LogRecord(java.util.logging.LogRecord) Filter(java.util.logging.Filter) LabeledIntList(com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) LabeledIntList(com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList) Test(org.junit.Test)

Example 7 with LabeledIntList

use of com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList in project gax-java by googleapis.

the class BatcherImplTest method testElementsNotLeaking.

/**
 * Validates that the elements are not leaking to multiple batches
 */
@Test(timeout = 500)
public void testElementsNotLeaking() throws Exception {
    ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
    ScheduledExecutorService multiThreadExecutor = Executors.newScheduledThreadPool(20);
    final AtomicBoolean isDuplicateElement = new AtomicBoolean(false);
    final ConcurrentMap<Integer, Boolean> map = new ConcurrentHashMap<>();
    final UnaryCallable<LabeledIntList, List<Integer>> callable = new UnaryCallable<LabeledIntList, List<Integer>>() {

        @Override
        public ApiFuture<List<Integer>> futureCall(LabeledIntList request, ApiCallContext context) {
            for (int val : request.ints) {
                Boolean isPresent = map.putIfAbsent(val, Boolean.TRUE);
                if (isPresent != null && isPresent) {
                    isDuplicateElement.set(true);
                    throw new AssertionError("Duplicate Element found");
                }
            }
            return ApiFutures.immediateFuture(request.ints);
        }
    };
    BatchingSettings settings = batchingSettings.toBuilder().setDelayThreshold(Duration.ofMillis(50)).build();
    try (final BatcherImpl<Integer, Integer, LabeledIntList, List<Integer>> batcherTest = new BatcherImpl<>(SQUARER_BATCHING_DESC_V2, callable, labeledIntList, settings, EXECUTOR)) {
        final Callable<Void> addElement = new Callable<Void>() {

            @Override
            public Void call() throws Exception {
                int counter = 0;
                while (!isDuplicateElement.get() && counter < 10_000) {
                    batcherTest.add(counter++);
                }
                return null;
            }
        };
        final Callable<Void> sendBatch = new Callable<Void>() {

            @Override
            public Void call() throws InterruptedException {
                batcherTest.flush();
                return null;
            }
        };
        // Started sequential element addition
        Future<Void> future = singleThreadExecutor.submit(addElement);
        for (int i = 0; !isDuplicateElement.get() && i < 3_000; i++) {
            multiThreadExecutor.submit(sendBatch);
        }
        // Closing the resources
        future.get();
        assertThat(isDuplicateElement.get()).isFalse();
        singleThreadExecutor.shutdown();
        multiThreadExecutor.shutdown();
    }
}
Also used : ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) UnaryCallable(com.google.api.gax.rpc.UnaryCallable) ApiCallContext(com.google.api.gax.rpc.ApiCallContext) LabeledIntSquarerCallable(com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntSquarerCallable) Callable(java.util.concurrent.Callable) UnaryCallable(com.google.api.gax.rpc.UnaryCallable) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) LabeledIntList(com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ExecutorService(java.util.concurrent.ExecutorService) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) LabeledIntList(com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Test(org.junit.Test)

Example 8 with LabeledIntList

use of com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList in project gax-java by googleapis.

the class BatcherImplTest method testCloseRace.

@Test
public void testCloseRace() throws ExecutionException, InterruptedException, TimeoutException {
    int iterations = 1_000_000;
    ExecutorService executor = Executors.newFixedThreadPool(100);
    try {
        List<Future<?>> closeFutures = new ArrayList<>();
        for (int i = 0; i < iterations; i++) {
            final SettableApiFuture<List<Integer>> result = SettableApiFuture.create();
            UnaryCallable<LabeledIntList, List<Integer>> callable = new UnaryCallable<LabeledIntList, List<Integer>>() {

                @Override
                public ApiFuture<List<Integer>> futureCall(LabeledIntList request, ApiCallContext context) {
                    return result;
                }
            };
            final Batcher<Integer, Integer> batcher = new BatcherImpl<>(SQUARER_BATCHING_DESC_V2, callable, labeledIntList, batchingSettings, EXECUTOR);
            batcher.add(1);
            executor.execute(new Runnable() {

                @Override
                public void run() {
                    result.set(ImmutableList.of(1));
                }
            });
            Future<?> f = executor.submit(new Runnable() {

                @Override
                public void run() {
                    try {
                        batcher.close();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        throw new RuntimeException(e);
                    }
                }
            });
            closeFutures.add(f);
        }
        // Make sure that none hang
        for (Future<?> f : closeFutures) {
            try {
                // Should never take this long, but padded just in case this runs on a limited machine
                f.get(1, TimeUnit.MINUTES);
            } catch (TimeoutException e) {
                assertWithMessage("BatcherImpl.close() is deadlocked").fail();
            }
        }
    } finally {
        executor.shutdownNow();
    }
}
Also used : UnaryCallable(com.google.api.gax.rpc.UnaryCallable) ArrayList(java.util.ArrayList) ApiCallContext(com.google.api.gax.rpc.ApiCallContext) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) FlowControlRuntimeException(com.google.api.gax.batching.FlowController.FlowControlRuntimeException) LabeledIntList(com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList) ThrowingRunnable(org.junit.function.ThrowingRunnable) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ExecutorService(java.util.concurrent.ExecutorService) ScheduledFuture(java.util.concurrent.ScheduledFuture) Future(java.util.concurrent.Future) ApiFuture(com.google.api.core.ApiFuture) SettableApiFuture(com.google.api.core.SettableApiFuture) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) LabeledIntList(com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList) TimeoutException(java.util.concurrent.TimeoutException) Test(org.junit.Test)

Example 9 with LabeledIntList

use of com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList in project gax-java by googleapis.

the class BatcherImplTest method testExceptionInDescriptorErrorHandling.

/**
 * Resolves future results when {@link BatchingDescriptor#splitException} throws exception
 */
@Test
public void testExceptionInDescriptorErrorHandling() throws InterruptedException {
    final RuntimeException fakeError = new RuntimeException("internal exception");
    BatchingDescriptor<Integer, Integer, LabeledIntList, List<Integer>> descriptor = new SquarerBatchingDescriptorV2() {

        @Override
        public void splitResponse(List<Integer> batchResponse, List<BatchEntry<Integer, Integer>> batch) {
            throw fakeError;
        }

        @Override
        public void splitException(Throwable throwable, List<BatchEntry<Integer, Integer>> batch) {
            throw fakeError;
        }
    };
    underTest = new BatcherImpl<>(descriptor, callLabeledIntSquarer, labeledIntList, batchingSettings, EXECUTOR);
    Future<Integer> result = underTest.add(2);
    underTest.flush();
    Throwable actualError = null;
    try {
        result.get();
    } catch (ExecutionException ex) {
        actualError = ex;
    }
    assertThat(actualError).hasCauseThat().isSameInstanceAs(fakeError);
    try {
        underTest.close();
    } catch (Exception ex) {
        actualError = ex;
    }
    assertThat(actualError).isInstanceOf(BatchingException.class);
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SquarerBatchingDescriptorV2(com.google.api.gax.rpc.testing.FakeBatchableApi.SquarerBatchingDescriptorV2) FlowControlRuntimeException(com.google.api.gax.batching.FlowController.FlowControlRuntimeException) LabeledIntList(com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) LabeledIntList(com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException) FlowControlRuntimeException(com.google.api.gax.batching.FlowController.FlowControlRuntimeException) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test)

Example 10 with LabeledIntList

use of com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList in project gax-java by googleapis.

the class BatcherImplTest method testExceptionInDescriptor.

/**
 * Resolves future results when {@link BatchingDescriptor#splitResponse} throws exception.
 */
@Test
public void testExceptionInDescriptor() throws InterruptedException {
    final RuntimeException fakeError = new RuntimeException("internal exception");
    BatchingDescriptor<Integer, Integer, LabeledIntList, List<Integer>> descriptor = new SquarerBatchingDescriptorV2() {

        @Override
        public void splitResponse(List<Integer> batchResponse, List<BatchEntry<Integer, Integer>> batch) {
            throw fakeError;
        }
    };
    underTest = new BatcherImpl<>(descriptor, callLabeledIntSquarer, labeledIntList, batchingSettings, EXECUTOR);
    Future<Integer> result = underTest.add(2);
    underTest.flush();
    Throwable actualError = null;
    try {
        result.get();
    } catch (ExecutionException ex) {
        actualError = ex;
    }
    assertThat(actualError).hasCauseThat().isSameInstanceAs(fakeError);
    try {
        underTest.close();
    } catch (Exception batchingEx) {
        actualError = batchingEx;
    }
    assertThat(actualError).isInstanceOf(BatchingException.class);
    assertThat(actualError).hasMessageThat().contains("Batching finished with 1 batches failed to apply due to: 1 RuntimeException and 0 " + "partial failures.");
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SquarerBatchingDescriptorV2(com.google.api.gax.rpc.testing.FakeBatchableApi.SquarerBatchingDescriptorV2) FlowControlRuntimeException(com.google.api.gax.batching.FlowController.FlowControlRuntimeException) LabeledIntList(com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) LabeledIntList(com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException) FlowControlRuntimeException(com.google.api.gax.batching.FlowController.FlowControlRuntimeException) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test)

Aggregations

LabeledIntList (com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntList)27 List (java.util.List)27 Test (org.junit.Test)27 ArrayList (java.util.ArrayList)16 ImmutableList (com.google.common.collect.ImmutableList)10 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)10 BatchingSettings (com.google.api.gax.batching.BatchingSettings)8 FlowControlRuntimeException (com.google.api.gax.batching.FlowController.FlowControlRuntimeException)6 ExecutionException (java.util.concurrent.ExecutionException)6 TimeoutException (java.util.concurrent.TimeoutException)6 ApiCallContext (com.google.api.gax.rpc.ApiCallContext)5 UnaryCallable (com.google.api.gax.rpc.UnaryCallable)4 SquarerBatchingDescriptorV2 (com.google.api.gax.rpc.testing.FakeBatchableApi.SquarerBatchingDescriptorV2)4 FlowControlSettings (com.google.api.gax.batching.FlowControlSettings)3 FlowController (com.google.api.gax.batching.FlowController)3 RetrySettings (com.google.api.gax.retrying.RetrySettings)3 SquarerBatchingDescriptor (com.google.api.gax.rpc.testing.FakeBatchableApi.SquarerBatchingDescriptor)3 StatusCode (com.google.api.gax.rpc.StatusCode)2 LabeledIntSquarerCallable (com.google.api.gax.rpc.testing.FakeBatchableApi.LabeledIntSquarerCallable)2 ExecutorService (java.util.concurrent.ExecutorService)2