Search in sources :

Example 1 with Futures

use of io.pravega.common.concurrent.Futures in project pravega by pravega.

the class Producer method runOneIteration.

// endregion
// region Producer Implementation
/**
 * Executes one iteration of the Producer.
 * 1. Requests a new ProducerOperation from the DataSource.
 * 2. Executes it.
 * 3. Completes the ProducerOperation with either success or failure based on the outcome step #2.
 */
private CompletableFuture<Void> runOneIteration() {
    this.iterationCount.incrementAndGet();
    val futures = new ArrayList<CompletableFuture<Void>>();
    for (int i = 0; i < this.config.getProducerParallelism(); i++) {
        ProducerOperation op = this.dataSource.nextOperation();
        if (op == null) {
            // Nothing more to do.
            this.canContinue.set(false);
            break;
        }
        CompletableFuture<Void> result;
        try {
            CompletableFuture<Void> waitOn = op.getWaitOn();
            if (waitOn != null) {
                result = waitOn.exceptionally(ex -> null).thenComposeAsync(v -> executeOperation(op), this.executorService);
            } else {
                result = executeOperation(op);
            }
        } catch (Throwable ex) {
            // Catch and handle sync errors.
            op.completed(-1);
            if (handleOperationError(ex, op)) {
                // Exception handled; skip this iteration since there's nothing more we can do.
                continue;
            } else {
                result = Futures.failedFuture(ex);
            }
        }
        futures.add(result.exceptionally(ex -> {
            // Catch and handle async errors.
            if (handleOperationError(ex, op)) {
                return null;
            }
            throw new CompletionException(ex);
        }));
    }
    return Futures.allOf(futures);
}
Also used : lombok.val(lombok.val) StoreAdapter(io.pravega.test.integration.selftest.adapters.StoreAdapter) SneakyThrows(lombok.SneakyThrows) Exceptions(io.pravega.common.Exceptions) lombok.val(lombok.val) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) CompletionException(java.util.concurrent.CompletionException) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) AbstractTimer(io.pravega.common.AbstractTimer) AtomicLong(java.util.concurrent.atomic.AtomicLong) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) NotImplementedException(org.apache.commons.lang.NotImplementedException) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) Futures(io.pravega.common.concurrent.Futures) CompletionException(java.util.concurrent.CompletionException) ArrayList(java.util.ArrayList)

Example 2 with Futures

use of io.pravega.common.concurrent.Futures in project pravega by pravega.

the class StreamSegmentContainerTests method activateAllSegments.

/**
 * Ensures that all Segments defined in the given collection are loaded up into the Container's metadata.
 * This is used to simplify a few tests that do not expect interference from StreamSegmentMapper's assignment logic
 * (that is, they execute operations in a certain order and assume that those ops are added to OperationProcessor queue
 * in that order; if StreamSegmentMapper interferes, there is no guarantee as to what this order will be).
 */
@SneakyThrows
private void activateAllSegments(Collection<String> segmentNames, TestContext context) {
    val futures = segmentNames.stream().map(s -> activateSegment(s, context.container)).collect(Collectors.toList());
    Futures.allOf(futures).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
}
Also used : lombok.val(lombok.val) Arrays(java.util.Arrays) Storage(io.pravega.segmentstore.storage.Storage) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) Cleanup(lombok.Cleanup) StorageWriterFactory(io.pravega.segmentstore.server.writer.StorageWriterFactory) Future(java.util.concurrent.Future) ReadResultEntryContents(io.pravega.segmentstore.contracts.ReadResultEntryContents) InMemoryStorageFactory(io.pravega.segmentstore.storage.mocks.InMemoryStorageFactory) Duration(java.time.Duration) Map(java.util.Map) AsyncReadResultProcessor(io.pravega.segmentstore.server.reading.AsyncReadResultProcessor) ContainerReadIndexFactory(io.pravega.segmentstore.server.reading.ContainerReadIndexFactory) InMemoryDurableDataLogFactory(io.pravega.segmentstore.storage.mocks.InMemoryDurableDataLogFactory) StreamSegmentStore(io.pravega.segmentstore.contracts.StreamSegmentStore) DurableLogFactory(io.pravega.segmentstore.server.logs.DurableLogFactory) Attributes(io.pravega.segmentstore.contracts.Attributes) DurableLogConfig(io.pravega.segmentstore.server.logs.DurableLogConfig) Writer(io.pravega.segmentstore.server.Writer) SegmentContainerFactory(io.pravega.segmentstore.server.SegmentContainerFactory) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) SyncStorage(io.pravega.segmentstore.storage.SyncStorage) Futures(io.pravega.common.concurrent.Futures) ByteArrayOutputStream(java.io.ByteArrayOutputStream) TooManyActiveSegmentsException(io.pravega.segmentstore.contracts.TooManyActiveSegmentsException) Exceptions(io.pravega.common.Exceptions) StorageFactory(io.pravega.segmentstore.storage.StorageFactory) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) Runnables(com.google.common.util.concurrent.Runnables) ReadIndexConfig(io.pravega.segmentstore.server.reading.ReadIndexConfig) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) Timeout(org.junit.rules.Timeout) ConfigurationException(io.pravega.common.util.ConfigurationException) StreamHelpers(io.pravega.common.io.StreamHelpers) WriterFactory(io.pravega.segmentstore.server.WriterFactory) Properties(java.util.Properties) DurableDataLog(io.pravega.segmentstore.storage.DurableDataLog) Executor(java.util.concurrent.Executor) lombok.val(lombok.val) OperationLog(io.pravega.segmentstore.server.OperationLog) Test(org.junit.Test) Service(com.google.common.util.concurrent.Service) AtomicLong(java.util.concurrent.atomic.AtomicLong) OperationLogFactory(io.pravega.segmentstore.server.OperationLogFactory) SegmentContainer(io.pravega.segmentstore.server.SegmentContainer) Assert(org.junit.Assert) WriterConfig(io.pravega.segmentstore.server.writer.WriterConfig) SneakyThrows(lombok.SneakyThrows) AssertExtensions(io.pravega.test.common.AssertExtensions) RequiredArgsConstructor(lombok.RequiredArgsConstructor) TimeoutException(java.util.concurrent.TimeoutException) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) ReadIndexFactory(io.pravega.segmentstore.server.ReadIndexFactory) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) StreamSegmentSealedException(io.pravega.segmentstore.contracts.StreamSegmentSealedException) SegmentHandle(io.pravega.segmentstore.storage.SegmentHandle) AbstractService(com.google.common.util.concurrent.AbstractService) CacheFactory(io.pravega.segmentstore.storage.CacheFactory) ServiceListeners(io.pravega.segmentstore.server.ServiceListeners) ContainerOfflineException(io.pravega.segmentstore.server.ContainerOfflineException) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ReadResultEntryType(io.pravega.segmentstore.contracts.ReadResultEntryType) UUID(java.util.UUID) DataLogWriterNotPrimaryException(io.pravega.segmentstore.storage.DataLogWriterNotPrimaryException) Collectors(java.util.stream.Collectors) SegmentMetadataComparer(io.pravega.segmentstore.server.SegmentMetadataComparer) StreamSegmentNameUtils(io.pravega.shared.segment.StreamSegmentNameUtils) List(java.util.List) InMemoryCacheFactory(io.pravega.segmentstore.storage.mocks.InMemoryCacheFactory) BadOffsetException(io.pravega.segmentstore.contracts.BadOffsetException) DurableDataLogFactory(io.pravega.segmentstore.storage.DurableDataLogFactory) ReadResult(io.pravega.segmentstore.contracts.ReadResult) Setter(lombok.Setter) Getter(lombok.Getter) ConfigHelpers(io.pravega.segmentstore.server.ConfigHelpers) AsyncStorageWrapper(io.pravega.segmentstore.storage.AsyncStorageWrapper) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) HashSet(java.util.HashSet) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) ReadResultEntry(io.pravega.segmentstore.contracts.ReadResultEntry) ExecutorService(java.util.concurrent.ExecutorService) ExecutorServiceHelpers.newScheduledThreadPool(io.pravega.common.concurrent.ExecutorServiceHelpers.newScheduledThreadPool) TimeoutTimer(io.pravega.common.TimeoutTimer) RollingStorage(io.pravega.segmentstore.storage.rolling.RollingStorage) IntentionalException(io.pravega.test.common.IntentionalException) StreamSegmentMergedException(io.pravega.segmentstore.contracts.StreamSegmentMergedException) TestReadResultHandler(io.pravega.segmentstore.server.reading.TestReadResultHandler) TestDurableDataLogFactory(io.pravega.segmentstore.server.TestDurableDataLogFactory) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Rule(org.junit.Rule) TypedProperties(io.pravega.common.util.TypedProperties) AttributeUpdateType(io.pravega.segmentstore.contracts.AttributeUpdateType) ReadIndex(io.pravega.segmentstore.server.ReadIndex) Collections(java.util.Collections) SneakyThrows(lombok.SneakyThrows)

Example 3 with Futures

use of io.pravega.common.concurrent.Futures in project pravega by pravega.

the class StreamSegmentStoreTestBase method waitForSegmentInStorage.

private CompletableFuture<Void> waitForSegmentInStorage(SegmentProperties sp, StreamSegmentStore readOnlyStore) {
    TimeoutTimer timer = new TimeoutTimer(TIMEOUT);
    AtomicBoolean tryAgain = new AtomicBoolean(true);
    return Futures.loop(tryAgain::get, () -> readOnlyStore.getStreamSegmentInfo(sp.getName(), false, TIMEOUT).thenCompose(storageProps -> {
        if (sp.isSealed()) {
            tryAgain.set(!storageProps.isSealed());
        } else {
            tryAgain.set(sp.getLength() != storageProps.getLength());
        }
        if (tryAgain.get() && !timer.hasRemaining()) {
            return Futures.<Void>failedFuture(new TimeoutException(String.format("Segment %s did not complete in Storage in the allotted time.", sp.getName())));
        } else {
            return Futures.delayedFuture(Duration.ofMillis(100), executorService());
        }
    }), executorService());
}
Also used : ByteArrayOutputStream(java.io.ByteArrayOutputStream) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) WriterConfig(io.pravega.segmentstore.server.writer.WriterConfig) SneakyThrows(lombok.SneakyThrows) AssertExtensions(io.pravega.test.common.AssertExtensions) Exceptions(io.pravega.common.Exceptions) TimeoutException(java.util.concurrent.TimeoutException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Cleanup(lombok.Cleanup) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) ReadResultEntryContents(io.pravega.segmentstore.contracts.ReadResultEntryContents) Duration(java.time.Duration) Map(java.util.Map) ReadResultEntry(io.pravega.segmentstore.contracts.ReadResultEntry) ContainerConfig(io.pravega.segmentstore.server.containers.ContainerConfig) ReadIndexConfig(io.pravega.segmentstore.server.reading.ReadIndexConfig) Timeout(org.junit.rules.Timeout) StreamHelpers(io.pravega.common.io.StreamHelpers) StreamSegmentStore(io.pravega.segmentstore.contracts.StreamSegmentStore) StreamSegmentTruncatedException(io.pravega.segmentstore.contracts.StreamSegmentTruncatedException) Properties(java.util.Properties) DurableLogConfig(io.pravega.segmentstore.server.logs.DurableLogConfig) TimeoutTimer(io.pravega.common.TimeoutTimer) Collection(java.util.Collection) lombok.val(lombok.val) IOException(java.io.IOException) Test(org.junit.Test) ReadResultEntryType(io.pravega.segmentstore.contracts.ReadResultEntryType) UUID(java.util.UUID) StreamSegmentNameUtils(io.pravega.shared.segment.StreamSegmentNameUtils) TimeUnit(java.util.concurrent.TimeUnit) Rule(org.junit.Rule) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) Assert(org.junit.Assert) Futures(io.pravega.common.concurrent.Futures) ReadResult(io.pravega.segmentstore.contracts.ReadResult) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) TimeoutTimer(io.pravega.common.TimeoutTimer) TimeoutException(java.util.concurrent.TimeoutException)

Example 4 with Futures

use of io.pravega.common.concurrent.Futures in project pravega by pravega.

the class OrderedItemProcessorTests method testClose.

/**
 * Tests that closing does cancel all pending items, except the processing ones.
 */
@Test
public void testClose() throws Exception {
    final int itemCount = 2 * CAPACITY;
    val processedItems = Collections.synchronizedCollection(new HashSet<Integer>());
    val processFuture = new CompletableFuture<Integer>();
    Function<Integer, CompletableFuture<Integer>> itemProcessor = i -> {
        if (!processedItems.add(i)) {
            Assert.fail("Duplicate item detected: " + i);
        }
        return processFuture;
    };
    val resultFutures = new ArrayList<CompletableFuture<Integer>>();
    @Cleanup val p = new TestProcessor(CAPACITY, itemProcessor, executorService());
    // Fill up to capacity, and beyond.
    for (int i = 0; i < itemCount; i++) {
        resultFutures.add(p.process(i));
    }
    val closeFuture = CompletableFuture.runAsync(p::close, executorService());
    // Verify none of the items have been completed (or cancelled for that matter).
    for (CompletableFuture<Integer> f : resultFutures) {
        Assert.assertFalse("Future was completed after close() was called.", f.isDone());
    }
    Assert.assertFalse("close() returned even if there are pending operations to complete.", closeFuture.isDone());
    processFuture.complete(0);
    // This will ensure that all result futures are completed.
    Futures.allOf(resultFutures).join();
    // This will ensure that the close() method returns.
    closeFuture.join();
}
Also used : lombok.val(lombok.val) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ObjectClosedException(io.pravega.common.ObjectClosedException) Setter(lombok.Setter) Getter(lombok.Getter) AssertExtensions(io.pravega.test.common.AssertExtensions) Cleanup(lombok.Cleanup) Random(java.util.Random) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Timeout(org.junit.rules.Timeout) Executor(java.util.concurrent.Executor) Semaphore(java.util.concurrent.Semaphore) IntentionalException(io.pravega.test.common.IntentionalException) lombok.val(lombok.val) Test(org.junit.Test) TimeUnit(java.util.concurrent.TimeUnit) Rule(org.junit.Rule) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) Assert(org.junit.Assert) Collections(java.util.Collections) Futures(io.pravega.common.concurrent.Futures) Cleanup(lombok.Cleanup) CompletableFuture(java.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList) Cleanup(lombok.Cleanup) Test(org.junit.Test)

Example 5 with Futures

use of io.pravega.common.concurrent.Futures in project pravega by pravega.

the class OrderedItemProcessorTests method testCapacityNotExceeded.

/**
 * Tests a scenario where we add fewer items than the capacity allows. We want to verify that none of the items are
 * queued up.
 */
@Test
public void testCapacityNotExceeded() throws Exception {
    val processedItems = Collections.synchronizedCollection(new HashSet<Integer>());
    val processFutures = Collections.synchronizedList(new ArrayList<CompletableFuture<Integer>>());
    Function<Integer, CompletableFuture<Integer>> itemProcessor = i -> {
        if (!processedItems.add(i)) {
            Assert.fail("Duplicate item detected: " + i);
        }
        CompletableFuture<Integer> result = new CompletableFuture<>();
        processFutures.add(result);
        return result;
    };
    val resultFutures = new ArrayList<CompletableFuture<Integer>>();
    @Cleanup val p = new TestProcessor(CAPACITY, itemProcessor, executorService());
    for (int i = 0; i < CAPACITY; i++) {
        resultFutures.add(p.process(i));
        Assert.assertTrue("Item has not been immediately processed when under capacity: " + i, processedItems.contains(i));
    }
    // Finish up half the futures. We need a Semaphore so that we know when the OrderedItemProcessor actually
    // finished cleaning up after these completed tasks, as that happens asynchronously inside the processor and we
    // don't really have a hook into it, except by sub-classing it and intercepting 'executionComplete'.
    val half = CAPACITY / 2;
    val cleanupSignal = new Semaphore(half);
    cleanupSignal.acquire(half);
    p.setExecutionCompleteCallback(cleanupSignal::release);
    for (int i = 0; i < half; i++) {
        processFutures.get(i).complete(TRANSFORMER.apply(i));
    }
    // Wait until the processor finished internal cleanups.
    cleanupSignal.acquire(half);
    Futures.allOf(resultFutures.subList(0, half)).join();
    // Now add even more and make sure we are under capacity.
    for (int i = 0; i < CAPACITY / 2; i++) {
        val item = CAPACITY + i;
        resultFutures.add(p.process(item));
        Assert.assertTrue("Item has not been immediately processed when under capacity: " + item, processedItems.contains(item));
    }
    // Finish up the remaining futures.
    for (int i = 0; i < processFutures.size(); i++) {
        val f = processFutures.get(i);
        if (!f.isDone()) {
            f.complete(TRANSFORMER.apply(i));
        }
    }
    // Verify they have been executed in order.
    val results = Futures.allOfWithResults(resultFutures).join();
    for (int i = 0; i < results.size(); i++) {
        Assert.assertEquals("Unexpected result at index " + i, TRANSFORMER.apply(i), results.get(i));
    }
}
Also used : lombok.val(lombok.val) ObjectClosedException(io.pravega.common.ObjectClosedException) Setter(lombok.Setter) Getter(lombok.Getter) AssertExtensions(io.pravega.test.common.AssertExtensions) Cleanup(lombok.Cleanup) Random(java.util.Random) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Timeout(org.junit.rules.Timeout) Executor(java.util.concurrent.Executor) Semaphore(java.util.concurrent.Semaphore) IntentionalException(io.pravega.test.common.IntentionalException) lombok.val(lombok.val) Test(org.junit.Test) TimeUnit(java.util.concurrent.TimeUnit) Rule(org.junit.Rule) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) Assert(org.junit.Assert) Collections(java.util.Collections) Futures(io.pravega.common.concurrent.Futures) ArrayList(java.util.ArrayList) Semaphore(java.util.concurrent.Semaphore) Cleanup(lombok.Cleanup) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CompletableFuture(java.util.concurrent.CompletableFuture) Test(org.junit.Test)

Aggregations

Futures (io.pravega.common.concurrent.Futures)5 ArrayList (java.util.ArrayList)5 CompletableFuture (java.util.concurrent.CompletableFuture)5 lombok.val (lombok.val)5 AssertExtensions (io.pravega.test.common.AssertExtensions)4 ThreadPooledTestSuite (io.pravega.test.common.ThreadPooledTestSuite)4 Duration (java.time.Duration)4 TimeUnit (java.util.concurrent.TimeUnit)4 Supplier (java.util.function.Supplier)4 Cleanup (lombok.Cleanup)4 Assert (org.junit.Assert)4 Rule (org.junit.Rule)4 Test (org.junit.Test)4 Timeout (org.junit.rules.Timeout)4 Exceptions (io.pravega.common.Exceptions)3 IntentionalException (io.pravega.test.common.IntentionalException)3 Collections (java.util.Collections)3 HashSet (java.util.HashSet)3 Executor (java.util.concurrent.Executor)3 Function (java.util.function.Function)3