Search in sources :

Example 1 with TooManyActiveSegmentsException

use of io.pravega.segmentstore.contracts.TooManyActiveSegmentsException in project pravega by pravega.

the class StreamSegmentContainerTests method tryActivate.

/**
 * Attempts to activate the targetSegment in the given Container. Since we do not have access to the internals of the
 * Container, we need to trigger this somehow, hence the need for this complex code. We need to trigger a truncation,
 * so we need an 'appendSegment' to which we continuously append so that the DurableDataLog is truncated. After truncation,
 * the Metadata should have enough leeway in making room for new activation.
 *
 * @return A Future that will complete either with an exception (failure) or SegmentProperties for the targetSegment.
 */
private CompletableFuture<SegmentProperties> tryActivate(MetadataCleanupContainer localContainer, String targetSegment, String appendSegment) {
    CompletableFuture<SegmentProperties> successfulMap = new CompletableFuture<>();
    // Append continuously to an existing segment in order to trigger truncations (these are necessary for forced evictions).
    val appendFuture = localContainer.appendRandomly(appendSegment, false, () -> !successfulMap.isDone());
    Futures.exceptionListener(appendFuture, successfulMap::completeExceptionally);
    // Repeatedly try to get info on 'segment1' (activate it), until we succeed or time out.
    TimeoutTimer remaining = new TimeoutTimer(TIMEOUT);
    Futures.loop(() -> !successfulMap.isDone(), () -> Futures.delayedFuture(Duration.ofMillis(EVICTION_SEGMENT_EXPIRATION_MILLIS_SHORT), executorService()).thenCompose(v -> localContainer.getStreamSegmentInfo(targetSegment, TIMEOUT)).thenAccept(successfulMap::complete).exceptionally(ex -> {
        if (!(Exceptions.unwrap(ex) instanceof TooManyActiveSegmentsException)) {
            // Some other error.
            successfulMap.completeExceptionally(ex);
        } else if (!remaining.hasRemaining()) {
            // Waited too long.
            successfulMap.completeExceptionally(new TimeoutException("No successful activation could be done in the allotted time."));
        }
        // Try again.
        return null;
    }), executorService());
    return successfulMap;
}
Also used : lombok.val(lombok.val) Arrays(java.util.Arrays) Storage(io.pravega.segmentstore.storage.Storage) StreamSegmentInformation(io.pravega.segmentstore.contracts.StreamSegmentInformation) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) ContainerEventProcessor(io.pravega.segmentstore.server.ContainerEventProcessor) Cleanup(lombok.Cleanup) StorageWriterFactory(io.pravega.segmentstore.server.writer.StorageWriterFactory) UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) Future(java.util.concurrent.Future) ContainerTableExtensionImpl(io.pravega.segmentstore.server.tables.ContainerTableExtensionImpl) InMemoryStorageFactory(io.pravega.segmentstore.storage.mocks.InMemoryStorageFactory) Duration(java.time.Duration) Map(java.util.Map) CachePolicy(io.pravega.segmentstore.server.CachePolicy) Operation(io.pravega.segmentstore.server.logs.operations.Operation) WriterFlushResult(io.pravega.segmentstore.server.WriterFlushResult) AsyncReadResultProcessor(io.pravega.segmentstore.server.reading.AsyncReadResultProcessor) ContainerReadIndexFactory(io.pravega.segmentstore.server.reading.ContainerReadIndexFactory) InMemoryDurableDataLogFactory(io.pravega.segmentstore.storage.mocks.InMemoryDurableDataLogFactory) 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) StandardCharsets(java.nio.charset.StandardCharsets) Stream(java.util.stream.Stream) SegmentContainerFactory(io.pravega.segmentstore.server.SegmentContainerFactory) ContainerTableExtension(io.pravega.segmentstore.server.tables.ContainerTableExtension) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) SyncStorage(io.pravega.segmentstore.storage.SyncStorage) DirectMemoryCache(io.pravega.segmentstore.storage.cache.DirectMemoryCache) TestUtils(io.pravega.test.common.TestUtils) Futures(io.pravega.common.concurrent.Futures) CacheManager(io.pravega.segmentstore.server.CacheManager) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IllegalContainerStateException(io.pravega.segmentstore.server.IllegalContainerStateException) TooManyActiveSegmentsException(io.pravega.segmentstore.contracts.TooManyActiveSegmentsException) EntrySerializerTests(io.pravega.segmentstore.server.tables.EntrySerializerTests) Exceptions(io.pravega.common.Exceptions) StorageFactory(io.pravega.segmentstore.storage.StorageFactory) BadAttributeUpdateException(io.pravega.segmentstore.contracts.BadAttributeUpdateException) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) SegmentType(io.pravega.segmentstore.contracts.SegmentType) Runnables(com.google.common.util.concurrent.Runnables) AttributeIndexConfig(io.pravega.segmentstore.server.attributes.AttributeIndexConfig) ReadIndexConfig(io.pravega.segmentstore.server.reading.ReadIndexConfig) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) BiConsumer(java.util.function.BiConsumer) Timeout(org.junit.rules.Timeout) WriterTableProcessor(io.pravega.segmentstore.server.tables.WriterTableProcessor) ConfigurationException(io.pravega.common.util.ConfigurationException) SegmentContainerExtension(io.pravega.segmentstore.server.SegmentContainerExtension) WriterFactory(io.pravega.segmentstore.server.WriterFactory) Properties(java.util.Properties) DurableDataLog(io.pravega.segmentstore.storage.DurableDataLog) Executor(java.util.concurrent.Executor) AttributeId(io.pravega.segmentstore.contracts.AttributeId) lombok.val(lombok.val) Assert.assertTrue(org.junit.Assert.assertTrue) OperationLog(io.pravega.segmentstore.server.OperationLog) TableExtensionConfig(io.pravega.segmentstore.server.tables.TableExtensionConfig) IOException(java.io.IOException) Test(org.junit.Test) SystemJournal(io.pravega.segmentstore.storage.chunklayer.SystemJournal) Service(com.google.common.util.concurrent.Service) AtomicLong(java.util.concurrent.atomic.AtomicLong) DirectSegmentAccess(io.pravega.segmentstore.server.DirectSegmentAccess) ContainerAttributeIndex(io.pravega.segmentstore.server.attributes.ContainerAttributeIndex) AttributeUpdateCollection(io.pravega.segmentstore.contracts.AttributeUpdateCollection) OperationLogFactory(io.pravega.segmentstore.server.OperationLogFactory) SegmentContainer(io.pravega.segmentstore.server.SegmentContainer) Assert(org.junit.Assert) TableEntry(io.pravega.segmentstore.contracts.tables.TableEntry) Assert.assertEquals(org.junit.Assert.assertEquals) DynamicAttributeValue(io.pravega.segmentstore.contracts.DynamicAttributeValue) OperationPriority(io.pravega.segmentstore.server.logs.operations.OperationPriority) WriterConfig(io.pravega.segmentstore.server.writer.WriterConfig) SneakyThrows(lombok.SneakyThrows) AssertExtensions(io.pravega.test.common.AssertExtensions) BiFunction(java.util.function.BiFunction) RequiredArgsConstructor(lombok.RequiredArgsConstructor) TimeoutException(java.util.concurrent.TimeoutException) ByteBuffer(java.nio.ByteBuffer) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) ReadIndexFactory(io.pravega.segmentstore.server.ReadIndexFactory) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) StreamSegmentSealedException(io.pravega.segmentstore.contracts.StreamSegmentSealedException) ContainerAttributeIndexFactoryImpl(io.pravega.segmentstore.server.attributes.ContainerAttributeIndexFactoryImpl) AttributeIndexFactory(io.pravega.segmentstore.server.attributes.AttributeIndexFactory) SegmentHandle(io.pravega.segmentstore.storage.SegmentHandle) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BufferView(io.pravega.common.util.BufferView) AbstractService(com.google.common.util.concurrent.AbstractService) AttributeIdLengthMismatchException(io.pravega.segmentstore.server.logs.AttributeIdLengthMismatchException) ServiceListeners(io.pravega.segmentstore.server.ServiceListeners) ContainerOfflineException(io.pravega.segmentstore.server.ContainerOfflineException) Predicate(java.util.function.Predicate) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) CompletionException(java.util.concurrent.CompletionException) ReadResultEntryType(io.pravega.segmentstore.contracts.ReadResultEntryType) UUID(java.util.UUID) DataLogWriterNotPrimaryException(io.pravega.segmentstore.storage.DataLogWriterNotPrimaryException) DynamicAttributeUpdate(io.pravega.segmentstore.contracts.DynamicAttributeUpdate) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) SegmentMetadataComparer(io.pravega.segmentstore.server.SegmentMetadataComparer) List(java.util.List) ByteArraySegment(io.pravega.common.util.ByteArraySegment) BadOffsetException(io.pravega.segmentstore.contracts.BadOffsetException) WriterSegmentProcessor(io.pravega.segmentstore.server.WriterSegmentProcessor) DurableDataLogFactory(io.pravega.segmentstore.storage.DurableDataLogFactory) ReadResult(io.pravega.segmentstore.contracts.ReadResult) IntStream(java.util.stream.IntStream) ObjectClosedException(io.pravega.common.ObjectClosedException) Setter(lombok.Setter) Getter(lombok.Getter) 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) CacheStorage(io.pravega.segmentstore.storage.cache.CacheStorage) HashSet(java.util.HashSet) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) ReadResultEntry(io.pravega.segmentstore.contracts.ReadResultEntry) ExecutorService(java.util.concurrent.ExecutorService) NameUtils(io.pravega.shared.NameUtils) 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) SnapshotInfo(io.pravega.segmentstore.storage.chunklayer.SnapshotInfo) TestDurableDataLogFactory(io.pravega.segmentstore.server.TestDurableDataLogFactory) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Rule(org.junit.Rule) SegmentOperation(io.pravega.segmentstore.server.SegmentOperation) CachedStreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.CachedStreamSegmentAppendOperation) TypedProperties(io.pravega.common.util.TypedProperties) AttributeUpdateType(io.pravega.segmentstore.contracts.AttributeUpdateType) ReadIndex(io.pravega.segmentstore.server.ReadIndex) Comparator(java.util.Comparator) Collections(java.util.Collections) StreamSegmentSealOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentSealOperation) InputStream(java.io.InputStream) CompletableFuture(java.util.concurrent.CompletableFuture) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) TooManyActiveSegmentsException(io.pravega.segmentstore.contracts.TooManyActiveSegmentsException) TimeoutTimer(io.pravega.common.TimeoutTimer) TimeoutException(java.util.concurrent.TimeoutException)

Example 2 with TooManyActiveSegmentsException

use of io.pravega.segmentstore.contracts.TooManyActiveSegmentsException in project pravega by pravega.

the class MetadataStoreTestBase method testGetOrAssignStreamSegmentIdWithMetadataLimit.

/**
 * Tests the ability of getOrAssignSegmentId to handle the TooManyActiveSegmentsException.
 */
@Test
public void testGetOrAssignStreamSegmentIdWithMetadataLimit() {
    List<String> segmentNames = Arrays.asList("S1", "S2", "S3");
    AtomicBoolean cleanupInvoked = new AtomicBoolean();
    AtomicInteger exceptionCounter = new AtomicInteger();
    Supplier<CompletableFuture<Void>> noOpCleanup = () -> {
        if (!cleanupInvoked.compareAndSet(false, true)) {
            return Futures.failedFuture(new AssertionError("Cleanup invoked multiple times."));
        }
        return CompletableFuture.completedFuture(null);
    };
    try (TestContext context = createTestContext(noOpCleanup)) {
        for (val s : segmentNames) {
            context.getMetadataStore().createSegment(s, SEGMENT_TYPE, null, TIMEOUT).join();
        }
        // 1. Verify the behavior when even after the retry we still cannot map.
        // We use 'containerId' as a proxy for the exception id (to make sure we collect the right one).
        context.connector.setMapSegmentId((id, sp, pin, timeout) -> Futures.failedFuture(new TooManyActiveSegmentsException(exceptionCounter.incrementAndGet(), 0)));
        AssertExtensions.assertSuppliedFutureThrows("Unexpected outcome when trying to map a segment to a full metadata that cannot be cleaned.", () -> context.getMetadataStore().getOrAssignSegmentId(segmentNames.get(0), TIMEOUT), ex -> ex instanceof TooManyActiveSegmentsException && ((TooManyActiveSegmentsException) ex).getContainerId() == exceptionCounter.get());
        Assert.assertEquals("Unexpected number of attempts to map.", 2, exceptionCounter.get());
        Assert.assertTrue("Cleanup was not invoked.", cleanupInvoked.get());
        // Now with a Segment 3.
        exceptionCounter.set(0);
        cleanupInvoked.set(false);
        AssertExtensions.assertSuppliedFutureThrows("Unexpected outcome when trying to map a Segment to a full metadata that cannot be cleaned.", () -> context.getMetadataStore().getOrAssignSegmentId(segmentNames.get(2), TIMEOUT), ex -> ex instanceof TooManyActiveSegmentsException && ((TooManyActiveSegmentsException) ex).getContainerId() == exceptionCounter.get());
        Assert.assertEquals("Unexpected number of attempts to map.", 2, exceptionCounter.get());
        Assert.assertTrue("Cleanup was not invoked.", cleanupInvoked.get());
    }
    // 2. Verify the behavior when the first call fails, but the second one succeeds.
    exceptionCounter.set(0);
    cleanupInvoked.set(false);
    Supplier<CompletableFuture<Void>> workingCleanup = () -> {
        if (!cleanupInvoked.compareAndSet(false, true)) {
            return Futures.failedFuture(new AssertionError("Cleanup invoked multiple times."));
        }
        return CompletableFuture.completedFuture(null);
    };
    try (TestContext context = createTestContext(workingCleanup)) {
        for (val s : segmentNames) {
            context.getMetadataStore().createSegment(s, SEGMENT_TYPE, null, TIMEOUT).join();
        }
        // 1. Verify the behavior when even after the retry we still cannot map.
        // We use 'containerId' as a proxy for the exception id (to make sure we collect the right one).
        context.connector.setMapSegmentId((id, sp, pin, timeout) -> {
            context.connector.reset();
            return Futures.failedFuture(new TooManyActiveSegmentsException(exceptionCounter.incrementAndGet(), 0));
        });
        long id = context.getMetadataStore().getOrAssignSegmentId(segmentNames.get(0), TIMEOUT).join();
        Assert.assertEquals("Unexpected number of attempts to map.", 1, exceptionCounter.get());
        Assert.assertTrue("Cleanup was not invoked.", cleanupInvoked.get());
        Assert.assertNotEquals("No valid SegmentId assigned.", ContainerMetadata.NO_STREAM_SEGMENT_ID, id);
    }
}
Also used : lombok.val(lombok.val) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TooManyActiveSegmentsException(io.pravega.segmentstore.contracts.TooManyActiveSegmentsException) Test(org.junit.Test)

Example 3 with TooManyActiveSegmentsException

use of io.pravega.segmentstore.contracts.TooManyActiveSegmentsException in project pravega by pravega.

the class StreamSegmentMapperTests method testGetOrAssignStreamSegmentIdWithMetadataLimit.

/**
 * Tests the ability of getOrAssignStreamSegmentId to handle the TooManyActiveSegmentsException.
 */
@Test
public void testGetOrAssignStreamSegmentIdWithMetadataLimit() throws Exception {
    // We use different "parent" segment names because it is possible that, if the test runs fast enough, and the
    // StreamSegmentMapper does not clean up its state quickly enough, subsequent mapping attempts will piggyback
    // on the first one, and thus not execute the test as desired.
    final String segmentName = "Segment";
    final String transactionParent = "SegmentWithTxn";
    final String transactionName = StreamSegmentNameUtils.getTransactionNameFromId(transactionParent, UUID.randomUUID());
    HashSet<String> storageSegments = new HashSet<>(Arrays.asList(segmentName, transactionParent, transactionName));
    @Cleanup TestContext context = new TestContext();
    setupStorageGetHandler(context, storageSegments, name -> StreamSegmentInformation.builder().name(name).build());
    // 1. Verify the behavior when even after the retry we still cannot map.
    AtomicInteger exceptionCounter = new AtomicInteger();
    AtomicBoolean cleanupInvoked = new AtomicBoolean();
    // We use 'containerId' as a proxy for the exception id (to make sure we collect the right one).
    context.operationLog.addHandler = op -> Futures.failedFuture(new TooManyActiveSegmentsException(exceptionCounter.incrementAndGet(), 0));
    Supplier<CompletableFuture<Void>> noOpCleanup = () -> {
        if (!cleanupInvoked.compareAndSet(false, true)) {
            return Futures.failedFuture(new AssertionError("Cleanup invoked multiple times."));
        }
        return CompletableFuture.completedFuture(null);
    };
    val mapper1 = new StreamSegmentMapper(context.metadata, context.operationLog, context.stateStore, noOpCleanup, context.storage, executorService());
    AssertExtensions.assertThrows("Unexpected outcome when trying to map a segment to a full metadata that cannot be cleaned.", () -> mapper1.getOrAssignStreamSegmentId(segmentName, TIMEOUT), ex -> ex instanceof TooManyActiveSegmentsException && ((TooManyActiveSegmentsException) ex).getContainerId() == exceptionCounter.get());
    Assert.assertEquals("Unexpected number of attempts to map.", 2, exceptionCounter.get());
    Assert.assertTrue("Cleanup was not invoked.", cleanupInvoked.get());
    // Now with a transaction.
    exceptionCounter.set(0);
    cleanupInvoked.set(false);
    AssertExtensions.assertThrows("Unexpected outcome when trying to map a transaction to a full metadata that cannot be cleaned.", () -> mapper1.getOrAssignStreamSegmentId(transactionName, TIMEOUT), ex -> ex instanceof TooManyActiveSegmentsException && ((TooManyActiveSegmentsException) ex).getContainerId() == exceptionCounter.get());
    Assert.assertEquals("Unexpected number of attempts to map.", 2, exceptionCounter.get());
    Assert.assertTrue("Cleanup was not invoked.", cleanupInvoked.get());
    // 2. Verify the behavior when the first call fails, but the second one succeeds.
    exceptionCounter.set(0);
    cleanupInvoked.set(false);
    Supplier<CompletableFuture<Void>> workingCleanup = () -> {
        if (!cleanupInvoked.compareAndSet(false, true)) {
            return Futures.failedFuture(new AssertionError("Cleanup invoked multiple times."));
        }
        // Setup the OperationLog to function correctly.
        setupOperationLog(context);
        return CompletableFuture.completedFuture(null);
    };
    val mapper2 = new StreamSegmentMapper(context.metadata, context.operationLog, context.stateStore, workingCleanup, context.storage, executorService());
    long id = mapper2.getOrAssignStreamSegmentId(segmentName, TIMEOUT).join();
    Assert.assertEquals("Unexpected number of attempts to map.", 1, exceptionCounter.get());
    Assert.assertTrue("Cleanup was not invoked.", cleanupInvoked.get());
    Assert.assertNotEquals("No valid SegmentId assigned.", ContainerMetadata.NO_STREAM_SEGMENT_ID, id);
}
Also used : lombok.val(lombok.val) TooManyActiveSegmentsException(io.pravega.segmentstore.contracts.TooManyActiveSegmentsException) Cleanup(lombok.Cleanup) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 4 with TooManyActiveSegmentsException

use of io.pravega.segmentstore.contracts.TooManyActiveSegmentsException in project pravega by pravega.

the class StreamSegmentContainerTests method testForcedMetadataCleanup.

/**
 * Tests the case when the ContainerMetadata has filled up to capacity (with segments and we cannot map anymore segments).
 */
@Test
public void testForcedMetadataCleanup() throws Exception {
    final int maxSegmentCount = 3;
    final int createdSegmentCount = maxSegmentCount * 2;
    final ContainerConfig containerConfig = ContainerConfig.builder().with(ContainerConfig.SEGMENT_METADATA_EXPIRATION_SECONDS, (int) DEFAULT_CONFIG.getSegmentMetadataExpiration().getSeconds()).with(ContainerConfig.MAX_ACTIVE_SEGMENT_COUNT, maxSegmentCount + EXPECTED_PINNED_SEGMENT_COUNT).with(ContainerConfig.STORAGE_SNAPSHOT_TIMEOUT_SECONDS, (int) DEFAULT_CONFIG.getStorageSnapshotTimeout().getSeconds()).build();
    // We need a special DL config so that we can force truncations after every operation - this will speed up metadata
    // eviction eligibility.
    final DurableLogConfig durableLogConfig = DurableLogConfig.builder().with(DurableLogConfig.CHECKPOINT_MIN_COMMIT_COUNT, 1).with(DurableLogConfig.CHECKPOINT_COMMIT_COUNT, 10).with(DurableLogConfig.CHECKPOINT_TOTAL_COMMIT_LENGTH, 10L * 1024 * 1024).build();
    @Cleanup TestContext context = createContext(containerConfig);
    OperationLogFactory localDurableLogFactory = new DurableLogFactory(durableLogConfig, context.dataLogFactory, executorService());
    @Cleanup MetadataCleanupContainer localContainer = new MetadataCleanupContainer(CONTAINER_ID, containerConfig, localDurableLogFactory, context.readIndexFactory, context.attributeIndexFactory, context.writerFactory, context.storageFactory, context.getDefaultExtensions(), executorService());
    localContainer.startAsync().awaitRunning();
    // Create the segments.
    val segments = new ArrayList<String>();
    for (int i = 0; i < createdSegmentCount; i++) {
        String name = getSegmentName(i);
        segments.add(name);
        localContainer.createStreamSegment(name, getSegmentType(name), null, TIMEOUT).join();
    }
    // Activate three segments (this should fill up available capacity).
    activateSegment(segments.get(2), localContainer).join();
    activateSegment(segments.get(4), localContainer).join();
    activateSegment(segments.get(5), localContainer).join();
    // At this point, the active segments should be: 2, 4 and 5.
    // Verify we cannot activate any other segment.
    AssertExtensions.assertSuppliedFutureThrows("getSegmentId() allowed mapping more segments than the metadata can support.", () -> activateSegment(segments.get(1), localContainer), ex -> ex instanceof TooManyActiveSegmentsException);
    // Test the ability to forcefully evict items from the metadata when there is pressure and we need to register something new.
    // Case 1: following a Segment deletion.
    localContainer.deleteStreamSegment(segments.get(2), TIMEOUT).join();
    val segment1Activation = tryActivate(localContainer, segments.get(1), segments.get(4));
    val segment1Info = segment1Activation.get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
    Assert.assertNotNull("Unable to properly activate dormant segment (1).", segment1Info);
    // Case 2: following a Merge.
    localContainer.sealStreamSegment(segments.get(5), TIMEOUT).join();
    localContainer.mergeStreamSegment(segments.get(4), segments.get(5), TIMEOUT).join();
    val segment0Activation = tryActivate(localContainer, segments.get(0), segments.get(3));
    val segment0Info = segment0Activation.get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
    Assert.assertNotNull("Unable to properly activate dormant segment (0).", segment0Info);
    tryActivate(localContainer, segments.get(1), segments.get(3)).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
    // At this point the active segments should be: 0, 1 and 3.
    Assert.assertNotNull("Pre-activated segment did not stay in metadata (3).", localContainer.getStreamSegmentInfo(segments.get(3), TIMEOUT).join());
    Assert.assertNotNull("Pre-activated segment did not stay in metadata (1).", localContainer.getStreamSegmentInfo(segments.get(1), TIMEOUT).join());
    Assert.assertNotNull("Pre-activated segment did not stay in metadata (0).", localContainer.getStreamSegmentInfo(segments.get(0), TIMEOUT).join());
    context.container.stopAsync().awaitTerminated();
}
Also used : lombok.val(lombok.val) DurableLogFactory(io.pravega.segmentstore.server.logs.DurableLogFactory) DurableLogConfig(io.pravega.segmentstore.server.logs.DurableLogConfig) ArrayList(java.util.ArrayList) TooManyActiveSegmentsException(io.pravega.segmentstore.contracts.TooManyActiveSegmentsException) Cleanup(lombok.Cleanup) OperationLogFactory(io.pravega.segmentstore.server.OperationLogFactory) Test(org.junit.Test)

Example 5 with TooManyActiveSegmentsException

use of io.pravega.segmentstore.contracts.TooManyActiveSegmentsException in project pravega by pravega.

the class ContainerMetadataUpdateTransactionTests method testSegmentMapMax.

/**
 * Tests the ability to reject new StreamSegment/Transaction map operations that would exceed the max allowed counts.
 */
@Test
public void testSegmentMapMax() throws Exception {
    UpdateableContainerMetadata metadata = new MetadataBuilder(CONTAINER_ID).withMaxActiveSegmentCount(3).build();
    metadata.mapStreamSegmentId("a", SEGMENT_ID);
    metadata.mapStreamSegmentId("b", 123457);
    // Non-recovery mode.
    val txn1 = createUpdateTransaction(metadata);
    // Map one segment, which should fill up the quota.
    StreamSegmentMapOperation acceptedMap = createMap();
    txn1.preProcessOperation(acceptedMap);
    txn1.acceptOperation(acceptedMap);
    // Verify non-recovery mode.
    AssertExtensions.assertThrows("Unexpected behavior from preProcessOperation when attempting to map a StreamSegment that would exceed the active segment quota.", () -> txn1.preProcessOperation(createMap("foo")), ex -> ex instanceof TooManyActiveSegmentsException);
    // Verify recovery mode.
    metadata.enterRecoveryMode();
    val txn2 = createUpdateTransaction(metadata);
    // updater.setOperationSequenceNumber(10000);
    StreamSegmentMapOperation secondMap = createMap("c");
    secondMap.setStreamSegmentId(1234);
    txn2.preProcessOperation(secondMap);
    txn2.acceptOperation(secondMap);
    StreamSegmentMapOperation thirdMap = createTransactionMap("a_txn2");
    thirdMap.setStreamSegmentId(1235);
    txn2.preProcessOperation(thirdMap);
    txn2.acceptOperation(thirdMap);
    txn2.commit(metadata);
    metadata.exitRecoveryMode();
    Assert.assertNotNull("Updater did not create metadata for new segment in recovery mode even if quota is exceeded (1).", metadata.getStreamSegmentMetadata(secondMap.getStreamSegmentId()));
    Assert.assertNotNull("Updater did not create metadata for new segment in recovery mode even if quota is exceeded (2).", metadata.getStreamSegmentMetadata(thirdMap.getStreamSegmentId()));
}
Also used : lombok.val(lombok.val) MetadataBuilder(io.pravega.segmentstore.server.MetadataBuilder) StreamSegmentMapOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentMapOperation) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) TooManyActiveSegmentsException(io.pravega.segmentstore.contracts.TooManyActiveSegmentsException) Test(org.junit.Test)

Aggregations

TooManyActiveSegmentsException (io.pravega.segmentstore.contracts.TooManyActiveSegmentsException)5 lombok.val (lombok.val)5 Test (org.junit.Test)5 CompletableFuture (java.util.concurrent.CompletableFuture)3 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 Cleanup (lombok.Cleanup)2 Sets (com.google.common.collect.Sets)1 AbstractService (com.google.common.util.concurrent.AbstractService)1 Runnables (com.google.common.util.concurrent.Runnables)1 Service (com.google.common.util.concurrent.Service)1 Exceptions (io.pravega.common.Exceptions)1 ObjectClosedException (io.pravega.common.ObjectClosedException)1 TimeoutTimer (io.pravega.common.TimeoutTimer)1 ExecutorServiceHelpers.newScheduledThreadPool (io.pravega.common.concurrent.ExecutorServiceHelpers.newScheduledThreadPool)1 Futures (io.pravega.common.concurrent.Futures)1 BufferView (io.pravega.common.util.BufferView)1 ByteArraySegment (io.pravega.common.util.ByteArraySegment)1 ConfigurationException (io.pravega.common.util.ConfigurationException)1 TypedProperties (io.pravega.common.util.TypedProperties)1