Search in sources :

Example 1 with WriterSegmentProcessor

use of io.pravega.segmentstore.server.WriterSegmentProcessor in project pravega by pravega.

the class AckCalculator method getHighestCommittedSequenceNumber.

/**
 * Determines the largest Sequence Number that can be safely truncated from the Writer's Data Source. All operations
 * up to, and including the one for this Sequence Number have been successfully committed to External Storage.
 *
 * The Sequence Number we acknowledge has the property that all operations up to, and including it, have been
 * committed to Storage.
 *
 * This can only be calculated by looking at all the active SegmentAggregators and picking the Lowest Uncommitted
 * Sequence Number (LUSN) among all of those Aggregators that have any outstanding data. The LUSN for each aggregator
 * has the property that, within the context of that Aggregator alone, all Operations that have a Sequence Number (SN)
 * smaller than LUSN have been committed to Storage. As such, picking the smallest of all LUSN values across
 * all the active SegmentAggregators will give us the highest SN that can be safely truncated out of the OperationLog.
 * Note that LUSN still points to an uncommitted Operation, so we need to subtract 1 from it to obtain the highest SN
 * that can be truncated up to (and including).
 *
 * If we have no active Aggregators, then we have committed all operations that were passed to us, so we can
 * safely truncate up to LastReadSequenceNumber.
 *
 * As opposed from {@link #getLowestUncommittedSequenceNumber}, this method should be called for
 * {@link WriterSegmentProcessor} instances that deal with different Segments.
 *
 * @param processors The {@link WriterSegmentProcessor} to inspect for commit status.
 * @param <T> {@link WriterSegmentProcessor} type.
 * @return The Highest Committed Sequence Number.
 */
<T extends WriterSegmentProcessor> long getHighestCommittedSequenceNumber(Iterable<T> processors) {
    long lowestUncommittedSeqNo = Long.MAX_VALUE;
    for (WriterSegmentProcessor a : processors) {
        if (!a.isClosed()) {
            long firstSeqNo = a.getLowestUncommittedSequenceNumber();
            if (firstSeqNo >= 0) {
                // Subtract 1 from the computed LUSN and then make sure it doesn't exceed the LastReadSequenceNumber
                // (it would only exceed it if there are no aggregators or of they are all empty - which means we processed everything).
                lowestUncommittedSeqNo = Math.min(lowestUncommittedSeqNo, firstSeqNo - 1);
            }
        }
    }
    lowestUncommittedSeqNo = Math.min(lowestUncommittedSeqNo, this.state.getLastReadSequenceNumber());
    return lowestUncommittedSeqNo;
}
Also used : WriterSegmentProcessor(io.pravega.segmentstore.server.WriterSegmentProcessor)

Example 2 with WriterSegmentProcessor

use of io.pravega.segmentstore.server.WriterSegmentProcessor in project pravega by pravega.

the class StorageWriterTests method testMultipleProcessors.

/**
 * Tests the StorageWriter with multiple Segment Processors.
 */
@Test
public void testMultipleProcessors() throws Exception {
    final int processorCount = 2;
    val processors = new HashMap<Long, ArrayList<WriterSegmentProcessor>>();
    WriterFactory.CreateProcessors createProcessors = sm -> {
        Assert.assertFalse("Processors already created for segment " + sm, processors.containsKey(sm.getId()));
        val result = new ArrayList<WriterSegmentProcessor>();
        for (int i = 0; i < processorCount; i++) {
            val p = new TestWriterProcessor();
            result.add(p);
        }
        processors.put(sm.getId(), result);
        return result;
    };
    @Cleanup TestContext context = new TestContext(DEFAULT_CONFIG, createProcessors);
    context.writer.startAsync();
    // Create a bunch of segments and Transactions.
    ArrayList<Long> segmentIds = createSegments(context);
    HashMap<Long, ArrayList<Long>> transactionsBySegment = createTransactions(segmentIds, context);
    ArrayList<Long> transactionIds = new ArrayList<>();
    transactionsBySegment.values().forEach(transactionIds::addAll);
    // Append data.
    HashMap<Long, ByteArrayOutputStream> segmentContents = new HashMap<>();
    appendDataBreadthFirst(segmentIds, segmentContents, context);
    appendDataBreadthFirst(transactionIds, segmentContents, context);
    sealSegments(transactionIds, context);
    mergeTransactions(transactionIds, segmentContents, context);
    sealSegments(segmentIds, context);
    // Wait for the writer to complete its job.
    metadataCheckpoint(context);
    context.dataSource.waitFullyAcked().get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
    // Verify the processors.
    for (val e : processors.entrySet()) {
        // Verify they received the same operations.
        val firstProcessor = (TestWriterProcessor) e.getValue().get(0);
        AssertExtensions.assertGreaterThan("Expected at least one operation.", 0, firstProcessor.operations.size());
        for (int i = 1; i < e.getValue().size(); i++) {
            AssertExtensions.assertListEquals("Not all processors for the same segment received the same operations.", firstProcessor.operations, ((TestWriterProcessor) e.getValue().get(i)).operations, Object::equals);
        }
        // Verify they have all been flushed.
        for (val p : e.getValue()) {
            Assert.assertEquals("Not all processors were flushed.", -1, p.getLowestUncommittedSequenceNumber());
        }
    }
    // Verify that the main Segment Aggregators were still able to do their jobs.
    verifyFinalOutput(segmentContents, transactionIds, context);
    context.writer.close();
    for (val e : processors.entrySet()) {
        for (val p : e.getValue()) {
            Assert.assertTrue("Not all processors were closed.", p.isClosed());
        }
    }
}
Also used : lombok.val(lombok.val) Arrays(java.util.Arrays) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) AssertExtensions(io.pravega.test.common.AssertExtensions) MergeSegmentOperation(io.pravega.segmentstore.server.logs.operations.MergeSegmentOperation) StorageNotPrimaryException(io.pravega.segmentstore.storage.StorageNotPrimaryException) RequiredArgsConstructor(lombok.RequiredArgsConstructor) TimeoutException(java.util.concurrent.TimeoutException) Cleanup(lombok.Cleanup) UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) StreamSegmentSealedException(io.pravega.segmentstore.contracts.StreamSegmentSealedException) SegmentHandle(io.pravega.segmentstore.storage.SegmentHandle) ByteArrayInputStream(java.io.ByteArrayInputStream) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Map(java.util.Map) Operation(io.pravega.segmentstore.server.logs.operations.Operation) WriterFlushResult(io.pravega.segmentstore.server.WriterFlushResult) StreamSegmentTruncateOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentTruncateOperation) ServiceListeners(io.pravega.segmentstore.server.ServiceListeners) Services(io.pravega.common.concurrent.Services) Attributes(io.pravega.segmentstore.contracts.Attributes) Predicate(java.util.function.Predicate) Collection(java.util.Collection) InMemoryStorage(io.pravega.segmentstore.storage.mocks.InMemoryStorage) UUID(java.util.UUID) DataLogWriterNotPrimaryException(io.pravega.segmentstore.storage.DataLogWriterNotPrimaryException) Collectors(java.util.stream.Collectors) ErrorInjector(io.pravega.test.common.ErrorInjector) List(java.util.List) ByteArraySegment(io.pravega.common.util.ByteArraySegment) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) WriterSegmentProcessor(io.pravega.segmentstore.server.WriterSegmentProcessor) TestStorage(io.pravega.segmentstore.server.TestStorage) MetadataBuilder(io.pravega.segmentstore.server.MetadataBuilder) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Exceptions(io.pravega.common.Exceptions) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) EvictableMetadata(io.pravega.segmentstore.server.EvictableMetadata) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) Timeout(org.junit.rules.Timeout) StreamSegmentMapOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentMapOperation) WriterFactory(io.pravega.segmentstore.server.WriterFactory) NameUtils(io.pravega.shared.NameUtils) UpdateAttributesOperation(io.pravega.segmentstore.server.logs.operations.UpdateAttributesOperation) AttributeId(io.pravega.segmentstore.contracts.AttributeId) IntentionalException(io.pravega.test.common.IntentionalException) lombok.val(lombok.val) MetadataCheckpointOperation(io.pravega.segmentstore.server.logs.operations.MetadataCheckpointOperation) IOException(java.io.IOException) Test(org.junit.Test) TimeUnit(java.util.concurrent.TimeUnit) AttributeUpdateCollection(io.pravega.segmentstore.contracts.AttributeUpdateCollection) Rule(org.junit.Rule) SegmentOperation(io.pravega.segmentstore.server.SegmentOperation) CachedStreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.CachedStreamSegmentAppendOperation) StreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentAppendOperation) AttributeUpdateType(io.pravega.segmentstore.contracts.AttributeUpdateType) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException) Assert(org.junit.Assert) Collections(java.util.Collections) StreamSegmentSealOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentSealOperation) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Cleanup(lombok.Cleanup) WriterFactory(io.pravega.segmentstore.server.WriterFactory) WriterSegmentProcessor(io.pravega.segmentstore.server.WriterSegmentProcessor) Test(org.junit.Test)

Aggregations

WriterSegmentProcessor (io.pravega.segmentstore.server.WriterSegmentProcessor)2 Exceptions (io.pravega.common.Exceptions)1 Services (io.pravega.common.concurrent.Services)1 ByteArraySegment (io.pravega.common.util.ByteArraySegment)1 AttributeId (io.pravega.segmentstore.contracts.AttributeId)1 AttributeUpdate (io.pravega.segmentstore.contracts.AttributeUpdate)1 AttributeUpdateCollection (io.pravega.segmentstore.contracts.AttributeUpdateCollection)1 AttributeUpdateType (io.pravega.segmentstore.contracts.AttributeUpdateType)1 Attributes (io.pravega.segmentstore.contracts.Attributes)1 SegmentProperties (io.pravega.segmentstore.contracts.SegmentProperties)1 StreamSegmentNotExistsException (io.pravega.segmentstore.contracts.StreamSegmentNotExistsException)1 StreamSegmentSealedException (io.pravega.segmentstore.contracts.StreamSegmentSealedException)1 DataCorruptionException (io.pravega.segmentstore.server.DataCorruptionException)1 EvictableMetadata (io.pravega.segmentstore.server.EvictableMetadata)1 MetadataBuilder (io.pravega.segmentstore.server.MetadataBuilder)1 SegmentMetadata (io.pravega.segmentstore.server.SegmentMetadata)1 SegmentOperation (io.pravega.segmentstore.server.SegmentOperation)1 ServiceListeners (io.pravega.segmentstore.server.ServiceListeners)1 TestStorage (io.pravega.segmentstore.server.TestStorage)1 UpdateableContainerMetadata (io.pravega.segmentstore.server.UpdateableContainerMetadata)1