Search in sources :

Example 26 with ReusableLatch

use of io.pravega.common.util.ReusableLatch in project pravega by pravega.

the class ThreadPoolScheduledExecutorServiceTest method testShutdownWithRecurring.

@Test(timeout = 10000)
public void testShutdownWithRecurring() throws Exception {
    ThreadPoolScheduledExecutorService pool = createPool(1);
    ReusableLatch latch = new ReusableLatch(false);
    AtomicInteger count = new AtomicInteger(0);
    AtomicReference<Exception> error = new AtomicReference<>();
    ScheduledFuture<?> future = pool.scheduleAtFixedRate(() -> {
        count.incrementAndGet();
        try {
            latch.await();
        } catch (Exception e) {
            error.set(e);
        }
    }, 0, 20, SECONDS);
    assertFalse(future.isCancelled());
    assertFalse(future.isDone());
    AssertExtensions.assertEventuallyEquals(1, count::get, 5000);
    pool.shutdown();
    latch.release();
    AssertExtensions.assertThrows(CancellationException.class, () -> future.get());
    assertTrue(future.isCancelled());
    assertTrue(future.isDone());
    assertEquals(1, count.get());
    assertTrue(pool.awaitTermination(1, SECONDS));
}
Also used : ReusableLatch(io.pravega.common.util.ReusableLatch) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicReference(java.util.concurrent.atomic.AtomicReference) CancellationException(java.util.concurrent.CancellationException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) Test(org.junit.Test)

Example 27 with ReusableLatch

use of io.pravega.common.util.ReusableLatch in project pravega by pravega.

the class ContainerEventProcessorTests method testReadWithFailingSegment.

/**
 * Test the behavior of the EventProcessor when internal Segment reads fail.
 *
 * @throws Exception
 */
@Test(timeout = 10000)
public void testReadWithFailingSegment() throws Exception {
    DirectSegmentAccess faultySegment = spy(new SegmentMock(this.executorService()));
    Function<String, CompletableFuture<DirectSegmentAccess>> faultySegmentSupplier = s -> CompletableFuture.completedFuture(faultySegment);
    @Cleanup ContainerEventProcessor eventProcessorService = new ContainerEventProcessorImpl(0, faultySegmentSupplier, ITERATION_DELAY, CONTAINER_OPERATION_TIMEOUT, this.executorService());
    int maxItemsProcessed = 10;
    int maxOutstandingBytes = 4 * 1024 * 1024;
    int truncationDataSize = 500;
    ContainerEventProcessor.EventProcessorConfig config = new ContainerEventProcessor.EventProcessorConfig(maxItemsProcessed, maxOutstandingBytes, truncationDataSize);
    ReusableLatch latch = new ReusableLatch();
    Function<List<BufferView>, CompletableFuture<Void>> doNothing = l -> {
        latch.release();
        return CompletableFuture.completedFuture(null);
    };
    // Make the internal Segment of the processor to fail upon a read.
    when(faultySegment.read(anyLong(), anyInt(), any(Duration.class))).thenThrow(IntentionalException.class).thenCallRealMethod();
    @Cleanup ContainerEventProcessor.EventProcessor processor = eventProcessorService.forConsumer("testSegmentMax", doNothing, config).get(TIMEOUT_FUTURE.toSeconds(), TimeUnit.SECONDS);
    // Write an event to make sure that the processor is running and await for it to be processed.
    BufferView event = new ByteArraySegment("Test".getBytes());
    processor.add(event, TIMEOUT_FUTURE).join();
    latch.await();
}
Also used : IntStream(java.util.stream.IntStream) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) ContainerEventProcessor(io.pravega.segmentstore.server.ContainerEventProcessor) AssertExtensions(io.pravega.test.common.AssertExtensions) Exceptions(io.pravega.common.Exceptions) Cleanup(lombok.Cleanup) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) Mockito.spy(org.mockito.Mockito.spy) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) BufferView(io.pravega.common.util.BufferView) Duration(java.time.Duration) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Timeout(org.junit.rules.Timeout) SerializationException(io.pravega.common.io.SerializationException) Mockito.anyLong(org.mockito.Mockito.anyLong) ReusableLatch(io.pravega.common.util.ReusableLatch) IntentionalException(io.pravega.test.common.IntentionalException) Test(org.junit.Test) IOException(java.io.IOException) CompletionException(java.util.concurrent.CompletionException) Mockito.times(org.mockito.Mockito.times) Mockito.when(org.mockito.Mockito.when) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) SegmentMock(io.pravega.segmentstore.server.SegmentMock) AtomicLong(java.util.concurrent.atomic.AtomicLong) DirectSegmentAccess(io.pravega.segmentstore.server.DirectSegmentAccess) List(java.util.List) Rule(org.junit.Rule) ByteArraySegment(io.pravega.common.util.ByteArraySegment) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) Mockito.anyInt(org.mockito.Mockito.anyInt) Assert(org.junit.Assert) Mockito.mock(org.mockito.Mockito.mock) ByteArraySegment(io.pravega.common.util.ByteArraySegment) SegmentMock(io.pravega.segmentstore.server.SegmentMock) Cleanup(lombok.Cleanup) IntentionalException(io.pravega.test.common.IntentionalException) ContainerEventProcessor(io.pravega.segmentstore.server.ContainerEventProcessor) CompletableFuture(java.util.concurrent.CompletableFuture) DirectSegmentAccess(io.pravega.segmentstore.server.DirectSegmentAccess) ReusableLatch(io.pravega.common.util.ReusableLatch) BufferView(io.pravega.common.util.BufferView) ArrayList(java.util.ArrayList) List(java.util.List) Test(org.junit.Test)

Example 28 with ReusableLatch

use of io.pravega.common.util.ReusableLatch in project pravega by pravega.

the class ContainerEventProcessorTests method testEventRejectionOnMaxOutstanding.

public static void testEventRejectionOnMaxOutstanding(ContainerEventProcessor eventProcessorService) throws Exception {
    int maxItemsProcessed = 1000;
    int maxOutstandingBytes = 1024 * 1024;
    int truncationDataSize = 500;
    ContainerEventProcessor.EventProcessorConfig config = new ContainerEventProcessor.EventProcessorConfig(maxItemsProcessed, maxOutstandingBytes, truncationDataSize);
    AtomicLong processorResults = new AtomicLong(0);
    ReusableLatch latch = new ReusableLatch();
    Function<List<BufferView>, CompletableFuture<Void>> handler = l -> {
        Exceptions.handleInterrupted(latch::await);
        processorResults.addAndGet(l.size());
        return CompletableFuture.completedFuture(null);
    };
    @Cleanup ContainerEventProcessor.EventProcessor processor = eventProcessorService.forConsumer("testSegmentMax", handler, config).get(TIMEOUT_FUTURE.toSeconds(), TimeUnit.SECONDS);
    boolean foundMaxOutstandingLimit = false;
    // Write a lot of data with the ContainerEventProcessor not started, so we ensure we get the max outstanding exception.
    BufferView event = new ByteArraySegment("This needs to be a long string to reach the limit sooner!!!".getBytes());
    while (!foundMaxOutstandingLimit) {
        try {
            processor.add(event, TIMEOUT_FUTURE).join();
            processorResults.decrementAndGet();
        } catch (Exception e) {
            // We have reached the max outstanding bytes for this internal Segment.
            Assert.assertTrue(e instanceof ContainerEventProcessor.TooManyOutstandingBytesException);
            foundMaxOutstandingLimit = true;
        }
    }
    latch.release();
    // Wait until all the events are consumed.
    AssertExtensions.assertEventuallyEquals(true, () -> processorResults.get() == 0, TIMEOUT_SUITE_MILLIS);
    // Check that we cannot add empty events.
    AssertExtensions.assertThrows(IllegalArgumentException.class, () -> processor.add(BufferView.empty(), TIMEOUT_FUTURE));
}
Also used : IntStream(java.util.stream.IntStream) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) ContainerEventProcessor(io.pravega.segmentstore.server.ContainerEventProcessor) AssertExtensions(io.pravega.test.common.AssertExtensions) Exceptions(io.pravega.common.Exceptions) Cleanup(lombok.Cleanup) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) Mockito.spy(org.mockito.Mockito.spy) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) BufferView(io.pravega.common.util.BufferView) Duration(java.time.Duration) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Timeout(org.junit.rules.Timeout) SerializationException(io.pravega.common.io.SerializationException) Mockito.anyLong(org.mockito.Mockito.anyLong) ReusableLatch(io.pravega.common.util.ReusableLatch) IntentionalException(io.pravega.test.common.IntentionalException) Test(org.junit.Test) IOException(java.io.IOException) CompletionException(java.util.concurrent.CompletionException) Mockito.times(org.mockito.Mockito.times) Mockito.when(org.mockito.Mockito.when) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) SegmentMock(io.pravega.segmentstore.server.SegmentMock) AtomicLong(java.util.concurrent.atomic.AtomicLong) DirectSegmentAccess(io.pravega.segmentstore.server.DirectSegmentAccess) List(java.util.List) Rule(org.junit.Rule) ByteArraySegment(io.pravega.common.util.ByteArraySegment) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) Mockito.anyInt(org.mockito.Mockito.anyInt) Assert(org.junit.Assert) Mockito.mock(org.mockito.Mockito.mock) ByteArraySegment(io.pravega.common.util.ByteArraySegment) Cleanup(lombok.Cleanup) SerializationException(io.pravega.common.io.SerializationException) IntentionalException(io.pravega.test.common.IntentionalException) IOException(java.io.IOException) CompletionException(java.util.concurrent.CompletionException) ContainerEventProcessor(io.pravega.segmentstore.server.ContainerEventProcessor) AtomicLong(java.util.concurrent.atomic.AtomicLong) CompletableFuture(java.util.concurrent.CompletableFuture) ReusableLatch(io.pravega.common.util.ReusableLatch) BufferView(io.pravega.common.util.BufferView) ArrayList(java.util.ArrayList) List(java.util.List)

Example 29 with ReusableLatch

use of io.pravega.common.util.ReusableLatch in project pravega by pravega.

the class ContainerEventProcessorTests method testBasicContainerEventProcessor.

public static void testBasicContainerEventProcessor(ContainerEventProcessor containerEventProcessor) throws Exception {
    int maxItemsPerBatch = 10;
    int maxOutstandingBytes = 4 * 1024 * 1024;
    int truncationDataSize = 500;
    ReusableLatch latch = new ReusableLatch();
    final AtomicReference<String> userEvent = new AtomicReference<>("event1");
    Function<List<BufferView>, CompletableFuture<Void>> handler = l -> {
        l.forEach(s -> Assert.assertEquals(userEvent.get().length(), s.getLength()));
        return CompletableFuture.runAsync(latch::release);
    };
    ContainerEventProcessor.EventProcessorConfig eventProcessorConfig = new ContainerEventProcessor.EventProcessorConfig(maxItemsPerBatch, maxOutstandingBytes, truncationDataSize);
    @Cleanup ContainerEventProcessor.EventProcessor processor = containerEventProcessor.forConsumer("testConsumer", handler, eventProcessorConfig).get(TIMEOUT_FUTURE.toSeconds(), TimeUnit.SECONDS);
    // Test adding one Event to the EventProcessor and wait for the handle to get executed and unblock this thread.
    BufferView event = new ByteArraySegment(userEvent.get().getBytes());
    processor.add(event, TIMEOUT_FUTURE).join();
    latch.await();
    latch.reset();
    // Test the same with a larger events.
    userEvent.set("longerEvent2");
    event = new ByteArraySegment(userEvent.get().getBytes());
    processor.add(event, TIMEOUT_FUTURE).join();
    processor.add(event, TIMEOUT_FUTURE).join();
    processor.add(event, TIMEOUT_FUTURE).join();
    latch.await();
    // Check that if the same EventProcessor name is used, the same object is retrieved.
    Assert.assertEquals(processor, containerEventProcessor.forConsumer("testConsumer", handler, eventProcessorConfig).get(TIMEOUT_FUTURE.toSeconds(), TimeUnit.SECONDS));
}
Also used : IntStream(java.util.stream.IntStream) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) ContainerEventProcessor(io.pravega.segmentstore.server.ContainerEventProcessor) AssertExtensions(io.pravega.test.common.AssertExtensions) Exceptions(io.pravega.common.Exceptions) Cleanup(lombok.Cleanup) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) Mockito.spy(org.mockito.Mockito.spy) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) BufferView(io.pravega.common.util.BufferView) Duration(java.time.Duration) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Timeout(org.junit.rules.Timeout) SerializationException(io.pravega.common.io.SerializationException) Mockito.anyLong(org.mockito.Mockito.anyLong) ReusableLatch(io.pravega.common.util.ReusableLatch) IntentionalException(io.pravega.test.common.IntentionalException) Test(org.junit.Test) IOException(java.io.IOException) CompletionException(java.util.concurrent.CompletionException) Mockito.times(org.mockito.Mockito.times) Mockito.when(org.mockito.Mockito.when) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) SegmentMock(io.pravega.segmentstore.server.SegmentMock) AtomicLong(java.util.concurrent.atomic.AtomicLong) DirectSegmentAccess(io.pravega.segmentstore.server.DirectSegmentAccess) List(java.util.List) Rule(org.junit.Rule) ByteArraySegment(io.pravega.common.util.ByteArraySegment) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) Mockito.anyInt(org.mockito.Mockito.anyInt) Assert(org.junit.Assert) Mockito.mock(org.mockito.Mockito.mock) ByteArraySegment(io.pravega.common.util.ByteArraySegment) AtomicReference(java.util.concurrent.atomic.AtomicReference) Cleanup(lombok.Cleanup) ContainerEventProcessor(io.pravega.segmentstore.server.ContainerEventProcessor) CompletableFuture(java.util.concurrent.CompletableFuture) ReusableLatch(io.pravega.common.util.ReusableLatch) BufferView(io.pravega.common.util.BufferView) ArrayList(java.util.ArrayList) List(java.util.List)

Example 30 with ReusableLatch

use of io.pravega.common.util.ReusableLatch in project pravega by pravega.

the class AsyncStorageWrapperTests method testConcurrencySameSegment.

/**
 * Tests basic same-segment concurrency for simple operations. Since all operations use the same sequencing mechanism
 * it suffices to test using two arbitrary operations instead of every possible pair.
 */
@Test
public void testConcurrencySameSegment() throws Exception {
    final String segmentName = "Segment";
    final String op1 = TestStorage.CREATE;
    final String op2 = TestStorage.DELETE;
    // Create a set of latches that can be used to detect when an operation was invoked and when to release it.
    val invoked = new HashMap<String, ReusableLatch>();
    val waitOn = new HashMap<String, ReusableLatch>();
    invoked.put(op1, new ReusableLatch());
    invoked.put(op2, new ReusableLatch());
    waitOn.put(op1, new ReusableLatch());
    waitOn.put(op2, new ReusableLatch());
    val innerStorage = new TestStorage((operation, segment) -> {
        invoked.get(operation).release();
        Exceptions.handleInterrupted(() -> waitOn.get(operation).await());
        return null;
    });
    @Cleanup val s = new AsyncStorageWrapper(innerStorage, executorService());
    // Begin executing one operation (Create) and wait for it properly "acquire" the lock.
    val futures = new ArrayList<CompletableFuture<?>>();
    futures.add(s.create(segmentName, TIMEOUT));
    invoked.get(op1).await(LOCK_TIMEOUT_MILLIS);
    Assert.assertEquals("Unexpected number of active segments.", 1, s.getSegmentWithOngoingOperationsCount());
    // Begin executing a second operation (Delete) and verify that it hasn't started within a reasonable amount of time.
    futures.add(s.delete(InMemoryStorage.newHandle(segmentName, false), TIMEOUT));
    AssertExtensions.assertThrows("Second operation was invoked while the first one was still running.", () -> invoked.get(op2).await(LOCK_TIMEOUT_MILLIS), ex -> ex instanceof TimeoutException);
    // Complete the first operation and await the second operation to begin executing, then release it too.
    waitOn.get(op1).release();
    invoked.get(op2).await(LOCK_TIMEOUT_MILLIS);
    Assert.assertEquals("Unexpected number of active segments.", 1, s.getSegmentWithOngoingOperationsCount());
    waitOn.get(op2).release();
    // Wait for both operations to complete. This will re-throw any exceptions that may have occurred.
    allOf(futures).get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
    Assert.assertEquals("Unexpected final number of active segments.", 0, s.getSegmentWithOngoingOperationsCount());
}
Also used : lombok.val(lombok.val) ReusableLatch(io.pravega.common.util.ReusableLatch) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Cleanup(lombok.Cleanup) TimeoutException(java.util.concurrent.TimeoutException) Test(org.junit.Test)

Aggregations

ReusableLatch (io.pravega.common.util.ReusableLatch)30 Test (org.junit.Test)30 Cleanup (lombok.Cleanup)25 CompletableFuture (java.util.concurrent.CompletableFuture)14 AtomicReference (java.util.concurrent.atomic.AtomicReference)14 lombok.val (lombok.val)14 AssertExtensions (io.pravega.test.common.AssertExtensions)13 IntentionalException (io.pravega.test.common.IntentionalException)13 IOException (java.io.IOException)13 TimeUnit (java.util.concurrent.TimeUnit)13 Exceptions (io.pravega.common.Exceptions)12 ArrayList (java.util.ArrayList)12 ByteArraySegment (io.pravega.common.util.ByteArraySegment)11 ThreadPooledTestSuite (io.pravega.test.common.ThreadPooledTestSuite)11 Duration (java.time.Duration)11 HashMap (java.util.HashMap)11 CancellationException (java.util.concurrent.CancellationException)11 CompletionException (java.util.concurrent.CompletionException)11 Assert (org.junit.Assert)11 Futures (io.pravega.common.concurrent.Futures)10