use of io.pravega.segmentstore.server.logs.operations.MergeTransactionOperation in project pravega by pravega.
the class SegmentAggregatorTests method generateSimpleMergeTransaction.
private StorageOperation generateSimpleMergeTransaction(long transactionId, TestContext context) {
UpdateableSegmentMetadata transactionMetadata = context.containerMetadata.getStreamSegmentMetadata(transactionId);
UpdateableSegmentMetadata parentMetadata = context.containerMetadata.getStreamSegmentMetadata(transactionMetadata.getParentId());
MergeTransactionOperation op = new MergeTransactionOperation(parentMetadata.getId(), transactionMetadata.getId());
op.setLength(transactionMetadata.getLength());
op.setStreamSegmentOffset(parentMetadata.getLength());
return op;
}
use of io.pravega.segmentstore.server.logs.operations.MergeTransactionOperation in project pravega by pravega.
the class ContainerMetadataUpdateTransactionTests method testPreProcessStreamSegmentAppend.
// region StreamSegmentAppendOperation
/**
* Tests the preProcess method with StreamSegmentAppend operations.
* Scenarios:
* * Recovery Mode
* * Non-recovery mode
* * StreamSegment is Merged (both in-transaction and in-metadata)
* * StreamSegment is Sealed (both in-transaction and in-metadata)
*/
@Test
public void testPreProcessStreamSegmentAppend() throws Exception {
val metadata = createMetadata();
StreamSegmentAppendOperation appendOp = createAppendNoOffset();
// When everything is OK (in recovery mode) - nothing should change.
metadata.enterRecoveryMode();
val txn1 = createUpdateTransaction(metadata);
txn1.preProcessOperation(appendOp);
AssertExtensions.assertLessThan("Unexpected StreamSegmentOffset after call to preProcess in recovery mode.", 0, appendOp.getStreamSegmentOffset());
checkNoSequenceNumberAssigned(appendOp, "call to preProcess in recovery mode");
Assert.assertEquals("preProcess(Append) seems to have changed the Updater internal state in recovery mode.", SEGMENT_LENGTH, txn1.getStreamSegmentMetadata(SEGMENT_ID).getLength());
Assert.assertEquals("preProcess(Append) seems to have changed the metadata in recovery mode.", SEGMENT_LENGTH, metadata.getStreamSegmentMetadata(SEGMENT_ID).getLength());
// When everything is OK (no recovery mode).
metadata.exitRecoveryMode();
val txn2 = createUpdateTransaction(metadata);
txn2.preProcessOperation(appendOp);
Assert.assertEquals("Unexpected StreamSegmentOffset after call to preProcess in non-recovery mode.", SEGMENT_LENGTH, appendOp.getStreamSegmentOffset());
checkNoSequenceNumberAssigned(appendOp, "call to preProcess in non-recovery mode");
Assert.assertEquals("preProcess(Append) seems to have changed the Updater internal state.", SEGMENT_LENGTH, txn2.getStreamSegmentMetadata(SEGMENT_ID).getLength());
Assert.assertEquals("preProcess(Append) seems to have changed the metadata.", SEGMENT_LENGTH, metadata.getStreamSegmentMetadata(SEGMENT_ID).getLength());
// When StreamSegment is merged (via transaction).
StreamSegmentAppendOperation transactionAppendOp = new StreamSegmentAppendOperation(SEALED_TRANSACTION_ID, DEFAULT_APPEND_DATA, null);
MergeTransactionOperation mergeOp = createMerge();
txn2.preProcessOperation(mergeOp);
txn2.acceptOperation(mergeOp);
Assert.assertFalse("Transaction should not be merged in metadata (yet).", metadata.getStreamSegmentMetadata(SEALED_TRANSACTION_ID).isMerged());
AssertExtensions.assertThrows("Unexpected behavior for preProcess(Append) when Segment is merged (in transaction).", () -> txn2.preProcessOperation(transactionAppendOp), ex -> ex instanceof StreamSegmentMergedException);
// When StreamSegment is merged (via metadata).
txn2.commit(metadata);
Assert.assertTrue("Transaction should have been merged in metadata.", metadata.getStreamSegmentMetadata(SEALED_TRANSACTION_ID).isMerged());
AssertExtensions.assertThrows("Unexpected behavior for preProcess(Append) when Segment is merged (in metadata).", () -> txn2.preProcessOperation(transactionAppendOp), ex -> ex instanceof StreamSegmentMergedException);
// When StreamSegment is sealed (via transaction).
StreamSegmentSealOperation sealOp = createSeal();
txn2.preProcessOperation(sealOp);
txn2.acceptOperation(sealOp);
Assert.assertFalse("StreamSegment should not be sealed in metadata (yet).", metadata.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
AssertExtensions.assertThrows("Unexpected behavior for preProcess(Append) when Segment is sealed (in transaction).", () -> txn2.preProcessOperation(createAppendNoOffset()), ex -> ex instanceof StreamSegmentSealedException);
// When StreamSegment is sealed (via metadata).
txn2.commit(metadata);
Assert.assertTrue("StreamSegment should have been sealed in metadata.", metadata.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
AssertExtensions.assertThrows("Unexpected behavior for preProcess(Append) when Segment is sealed (in metadata).", () -> txn2.preProcessOperation(createAppendNoOffset()), ex -> ex instanceof StreamSegmentSealedException);
}
use of io.pravega.segmentstore.server.logs.operations.MergeTransactionOperation in project pravega by pravega.
the class ContainerMetadataUpdateTransactionTests method testPreProcessStreamSegmentSeal.
// endregion
// region StreamSegmentSealOperation
/**
* Tests the preProcess method with StreamSegmentSeal operations.
* Scenarios:
* * Recovery Mode
* * Non-recovery mode
* * StreamSegment is Merged (both in-transaction and in-metadata)
* * StreamSegment is Sealed (both in-transaction and in-metadata)
*/
@Test
public void testPreProcessStreamSegmentSeal() throws Exception {
UpdateableContainerMetadata metadata = createMetadata();
StreamSegmentSealOperation sealOp = createSeal();
// When everything is OK (in recovery mode) - nothing should change.
metadata.enterRecoveryMode();
val txn1 = createUpdateTransaction(metadata);
txn1.preProcessOperation(sealOp);
AssertExtensions.assertLessThan("Unexpected StreamSegmentLength after call to preProcess in recovery mode.", 0, sealOp.getStreamSegmentOffset());
checkNoSequenceNumberAssigned(sealOp, "call to preProcess in recovery mode");
Assert.assertFalse("preProcess(Seal) seems to have changed the Updater internal state in recovery mode.", txn1.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
Assert.assertFalse("preProcess(Seal) seems to have changed the metadata in recovery mode.", metadata.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
// When everything is OK (no recovery mode).
metadata.exitRecoveryMode();
val txn2 = createUpdateTransaction(metadata);
txn2.preProcessOperation(sealOp);
Assert.assertEquals("Unexpected StreamSegmentLength after call to preProcess in non-recovery mode.", SEGMENT_LENGTH, sealOp.getStreamSegmentOffset());
checkNoSequenceNumberAssigned(sealOp, "call to preProcess in non-recovery mode");
Assert.assertFalse("preProcess(Seal) seems to have changed the Updater internal state.", txn2.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
Assert.assertFalse("preProcess(Seal) seems to have changed the metadata.", metadata.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
// When StreamSegment is merged (via transaction).
StreamSegmentSealOperation transactionSealOp = new StreamSegmentSealOperation(SEALED_TRANSACTION_ID);
MergeTransactionOperation mergeOp = createMerge();
txn2.preProcessOperation(mergeOp);
txn2.acceptOperation(mergeOp);
Assert.assertFalse("Transaction should not be merged in metadata (yet).", metadata.getStreamSegmentMetadata(SEALED_TRANSACTION_ID).isMerged());
AssertExtensions.assertThrows("Unexpected behavior for preProcess(Seal) when Segment is merged (in transaction).", () -> txn2.preProcessOperation(transactionSealOp), ex -> ex instanceof StreamSegmentMergedException);
// When StreamSegment is merged (via metadata).
txn2.commit(metadata);
Assert.assertTrue("Transaction should have been merged in metadata.", metadata.getStreamSegmentMetadata(SEALED_TRANSACTION_ID).isMerged());
AssertExtensions.assertThrows("Unexpected behavior for preProcess(Seal) when Segment is merged (in metadata).", () -> txn2.preProcessOperation(transactionSealOp), ex -> ex instanceof StreamSegmentMergedException);
// When StreamSegment is sealed (via transaction).
txn2.acceptOperation(sealOp);
Assert.assertFalse("StreamSegment should not be sealed in metadata (yet).", metadata.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
AssertExtensions.assertThrows("Unexpected behavior for preProcess(Seal) when Segment is sealed (in transaction).", () -> txn2.preProcessOperation(createSeal()), ex -> ex instanceof StreamSegmentSealedException);
// When StreamSegment is sealed (via metadata).
txn2.commit(metadata);
Assert.assertTrue("StreamSegment should have been sealed in metadata.", metadata.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
AssertExtensions.assertThrows("Unexpected behavior for preProcess(Seal) when Segment is sealed (in metadata).", () -> txn2.preProcessOperation(createSeal()), ex -> ex instanceof StreamSegmentSealedException);
}
use of io.pravega.segmentstore.server.logs.operations.MergeTransactionOperation in project pravega by pravega.
the class MemoryStateUpdater method addToReadIndex.
/**
* Registers the given operation in the ReadIndex.
*
* @param operation The operation to register.
*/
private void addToReadIndex(StorageOperation operation) {
try {
if (operation instanceof StreamSegmentAppendOperation) {
// Record a StreamSegmentAppendOperation. Just in case, we also support this type of operation, but we need to
// log a warning indicating so. This means we do not optimize memory properly, and we end up storing data
// in two different places.
StreamSegmentAppendOperation appendOperation = (StreamSegmentAppendOperation) operation;
this.readIndex.append(appendOperation.getStreamSegmentId(), appendOperation.getStreamSegmentOffset(), appendOperation.getData());
} else if (operation instanceof MergeTransactionOperation) {
// Record a MergeTransactionOperation. We call beginMerge here, and the StorageWriter will call completeMerge.
MergeTransactionOperation mergeOperation = (MergeTransactionOperation) operation;
this.readIndex.beginMerge(mergeOperation.getStreamSegmentId(), mergeOperation.getStreamSegmentOffset(), mergeOperation.getTransactionSegmentId());
} else {
assert !(operation instanceof CachedStreamSegmentAppendOperation) : "attempted to add a CachedStreamSegmentAppendOperation to the ReadIndex";
}
} catch (ObjectClosedException | StreamSegmentNotExistsException ex) {
// The Segment is in the process of being deleted. We usually end up in here because a concurrent delete
// request has updated the metadata while we were executing.
log.warn("Not adding operation '{}' to ReadIndex because it refers to a deleted StreamSegment.", operation);
}
}
use of io.pravega.segmentstore.server.logs.operations.MergeTransactionOperation in project pravega by pravega.
the class ContainerMetadataUpdateTransaction method preProcessOperation.
/**
* Pre-processes the given Operation. See OperationMetadataUpdater.preProcessOperation for more details on behavior.
*
* @param operation The operation to pre-process.
* @throws ContainerException If the given operation was rejected given the current state of the container metadata.
* @throws StreamSegmentException If the given operation was incompatible with the current state of the Segment.
* For example: StreamSegmentNotExistsException, StreamSegmentSealedException or
* StreamSegmentMergedException.
*/
void preProcessOperation(Operation operation) throws ContainerException, StreamSegmentException {
checkNotSealed();
SegmentMetadataUpdateTransaction segmentMetadata = null;
if (operation instanceof SegmentOperation) {
segmentMetadata = getSegmentUpdateTransaction(((SegmentOperation) operation).getStreamSegmentId());
if (segmentMetadata.isDeleted()) {
throw new StreamSegmentNotExistsException(segmentMetadata.getName());
}
}
if (operation instanceof StreamSegmentAppendOperation) {
segmentMetadata.preProcessOperation((StreamSegmentAppendOperation) operation);
} else if (operation instanceof StreamSegmentSealOperation) {
segmentMetadata.preProcessOperation((StreamSegmentSealOperation) operation);
} else if (operation instanceof MergeTransactionOperation) {
MergeTransactionOperation mbe = (MergeTransactionOperation) operation;
SegmentMetadataUpdateTransaction transactionMetadata = getSegmentUpdateTransaction(mbe.getTransactionSegmentId());
transactionMetadata.preProcessAsTransactionSegment(mbe);
segmentMetadata.preProcessAsParentSegment(mbe, transactionMetadata);
} else if (operation instanceof StreamSegmentMapOperation) {
preProcessMetadataOperation((StreamSegmentMapOperation) operation);
} else if (operation instanceof UpdateAttributesOperation) {
segmentMetadata.preProcessOperation((UpdateAttributesOperation) operation);
} else if (operation instanceof MetadataCheckpointOperation) {
// MetadataCheckpointOperations do not require preProcess and accept; they can be handled in a single stage.
processMetadataOperation((MetadataCheckpointOperation) operation);
} else if (operation instanceof StorageMetadataCheckpointOperation) {
// StorageMetadataCheckpointOperation do not require preProcess and accept; they can be handled in a single stage.
processMetadataOperation((StorageMetadataCheckpointOperation) operation);
} else if (operation instanceof StreamSegmentTruncateOperation) {
segmentMetadata.preProcessOperation((StreamSegmentTruncateOperation) operation);
}
}
Aggregations