use of io.pravega.controller.store.stream.VersionedTransactionData in project pravega by pravega.
the class TimeoutServiceTest method testTimeoutTaskFailureInvalidVersion.
@Test(timeout = 10000)
public void testTimeoutTaskFailureInvalidVersion() throws InterruptedException {
UUID txnId = streamStore.generateTransactionId(SCOPE, STREAM, null, executor).join();
VersionedTransactionData txData = streamStore.createTransaction(SCOPE, STREAM, txnId, LEASE, 10 * LEASE, null, executor).join();
// Submit transaction to TimeoutService with incorrect tx version identifier.
timeoutService.addTxn(SCOPE, STREAM, txData.getId(), getNextVersion(txData.getVersion()), LEASE, txData.getMaxExecutionExpiryTime());
Optional<Throwable> result = timeoutService.getTaskCompletionQueue().poll((long) (1.25 * LEASE + RETRY_DELAY), TimeUnit.MILLISECONDS);
Assert.assertNotNull(result);
Assert.assertTrue(result.isPresent());
Assert.assertEquals(StoreException.WriteConflictException.class, result.get().getClass());
TxnStatus status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join();
Assert.assertEquals(TxnStatus.OPEN, status);
}
use of io.pravega.controller.store.stream.VersionedTransactionData in project pravega by pravega.
the class TimeoutServiceTest method testControllerPingLeaseTooLarge.
@Test(timeout = 10000)
public void testControllerPingLeaseTooLarge() {
int lease = 10;
UUID txnId = controllerService.createTransaction(SCOPE, STREAM, lease, 9L).thenApply(x -> x.getKey()).join();
PingTxnStatus pingStatus = controllerService.pingTransaction(SCOPE, STREAM, txnId, Config.MAX_LEASE_VALUE + 1, 9L).join();
Assert.assertEquals(PingTxnStatus.Status.LEASE_TOO_LARGE, pingStatus.getStatus());
pingStatus = controllerService.pingTransaction(SCOPE, STREAM, txnId, 1000 * lease + 1, 9L).join();
Assert.assertEquals(PingTxnStatus.Status.MAX_EXECUTION_TIME_EXCEEDED, pingStatus.getStatus());
UUID txnId1 = streamStore.generateTransactionId(SCOPE, STREAM, null, executor).join();
VersionedTransactionData txData = streamStore.createTransaction(SCOPE, STREAM, txnId1, LEASE, 2 * LEASE, null, executor).join();
txnId = txData.getId();
pingStatus = controllerService.pingTransaction(SCOPE, STREAM, txnId, Config.MAX_LEASE_VALUE + 1, 9L).join();
Assert.assertEquals(PingTxnStatus.Status.LEASE_TOO_LARGE, pingStatus.getStatus());
pingStatus = controllerService.pingTransaction(SCOPE, STREAM, txnId, 3 * LEASE, 9L).join();
Assert.assertEquals(PingTxnStatus.Status.MAX_EXECUTION_TIME_EXCEEDED, pingStatus.getStatus());
}
use of io.pravega.controller.store.stream.VersionedTransactionData in project pravega by pravega.
the class RequestHandlersTest method concurrentTxnCommit.
private void concurrentTxnCommit(String stream, String func, boolean expectFailureOnFirstJob, Predicate<Throwable> firstExceptionPredicate, Map<String, Integer> invocationCount, int expectedVersion) throws Exception {
StreamMetadataStore streamStore1 = getStore();
StreamMetadataStore streamStore1Spied = spy(getStore());
StreamConfiguration config = StreamConfiguration.builder().scalingPolicy(ScalingPolicy.byEventRate(1, 2, 1)).build();
streamStore1.createStream(scope, stream, config, System.currentTimeMillis(), null, executor).join();
streamStore1.setState(scope, stream, State.ACTIVE, null, executor).join();
StreamMetadataStore streamStore2 = getStore();
CommitRequestHandler requestHandler1 = new CommitRequestHandler(streamStore1Spied, streamMetadataTasks, streamTransactionMetadataTasks, bucketStore, executor);
CommitRequestHandler requestHandler2 = new CommitRequestHandler(streamStore2, streamMetadataTasks, streamTransactionMetadataTasks, bucketStore, executor);
// create txn on epoch 0 and set it to committing
UUID txnId = streamStore1.generateTransactionId(scope, stream, null, executor).join();
VersionedTransactionData txnEpoch0 = streamStore1.createTransaction(scope, stream, txnId, 1000L, 10000L, null, executor).join();
streamStore1.sealTransaction(scope, stream, txnId, true, Optional.of(txnEpoch0.getVersion()), "", Long.MIN_VALUE, null, executor).join();
// regular commit
// start commit transactions
CompletableFuture<Void> wait = new CompletableFuture<>();
CompletableFuture<Void> signal = new CompletableFuture<>();
CommitEvent commitOnEpoch1 = new CommitEvent(scope, stream, 0);
setMockCommitTxnLatch(streamStore1, streamStore1Spied, func, signal, wait);
CompletableFuture<Void> future1 = CompletableFuture.completedFuture(null).thenComposeAsync(v -> requestHandler1.execute(commitOnEpoch1), executor);
signal.join();
// let this run to completion. this should succeed
requestHandler2.execute(commitOnEpoch1).join();
wait.complete(null);
if (expectFailureOnFirstJob) {
AssertExtensions.assertSuppliedFutureThrows("first commit should fail", () -> future1, firstExceptionPredicate);
} else {
future1.join();
}
verify(streamStore1Spied, times(invocationCount.get("startCommitTransactions"))).startCommitTransactions(anyString(), anyString(), anyInt(), any(), any());
verify(streamStore1Spied, times(invocationCount.get("completeCommitTransactions"))).completeCommitTransactions(anyString(), anyString(), any(), any(), any(), any());
verify(streamStore1Spied, times(invocationCount.get("updateVersionedState"))).updateVersionedState(anyString(), anyString(), any(), any(), any(), any());
VersionedMetadata<CommittingTransactionsRecord> versioned = streamStore1.getVersionedCommittingTransactionsRecord(scope, stream, null, executor).join();
assertEquals(CommittingTransactionsRecord.EMPTY, versioned.getObject());
assertEquals(expectedVersion, getVersionNumber(versioned.getVersion()));
assertEquals(State.ACTIVE, streamStore1.getState(scope, stream, true, null, executor).join());
streamStore1.close();
streamStore2.close();
}
use of io.pravega.controller.store.stream.VersionedTransactionData in project pravega by pravega.
the class ScaleRequestHandlerTest method testMigrateManualScaleRequestAfterRollingTxn.
@Test(timeout = 30000)
public void testMigrateManualScaleRequestAfterRollingTxn() throws Exception {
// This test checks a scenario where after rolling txn, if an outstanding scale request
// was present, its epoch consistency should fail
String stream = "newStream";
StreamConfiguration config = StreamConfiguration.builder().scalingPolicy(ScalingPolicy.byEventRate(1, 2, 2)).build();
streamMetadataTasks.createStream(scope, stream, config, System.currentTimeMillis(), 0L).get();
EventWriterMock writer = new EventWriterMock();
streamMetadataTasks.setRequestEventWriter(writer);
ScaleOperationTask scaleRequestHandler = new ScaleOperationTask(streamMetadataTasks, streamStore, executor);
StreamRequestHandler requestHandler = new StreamRequestHandler(null, scaleRequestHandler, null, null, null, null, null, null, null, streamStore, null, executor);
CommitRequestHandler commitRequestHandler = new CommitRequestHandler(streamStore, streamMetadataTasks, streamTransactionMetadataTasks, bucketStore, executor);
// 1 create transaction on old epoch and set it to committing
UUID txnIdOldEpoch = streamStore.generateTransactionId(scope, stream, null, executor).join();
VersionedTransactionData txnData = streamStore.createTransaction(scope, stream, txnIdOldEpoch, 10000, 10000, null, executor).join();
streamStore.sealTransaction(scope, stream, txnData.getId(), true, Optional.empty(), "", Long.MIN_VALUE, null, executor).join();
UUID txnIdOldEpoch2 = streamStore.generateTransactionId(scope, stream, null, executor).join();
VersionedTransactionData txnData2 = streamStore.createTransaction(scope, stream, txnIdOldEpoch2, 10000, 10000, null, executor).join();
streamStore.sealTransaction(scope, stream, txnData2.getId(), true, Optional.empty(), "", Long.MIN_VALUE, null, executor).join();
EpochRecord epochZero = streamStore.getActiveEpoch(scope, stream, null, true, executor).join();
assertEquals(0, epochZero.getEpoch());
// 2. start scale
requestHandler.process(new ScaleOpEvent(scope, stream, Lists.newArrayList(0L), Lists.newArrayList(new AbstractMap.SimpleEntry<>(0.0, 0.25), new AbstractMap.SimpleEntry<>(0.25, 0.5)), false, System.currentTimeMillis(), System.currentTimeMillis()), () -> false).join();
// 3. verify that scale is complete
State state = streamStore.getState(scope, stream, true, null, executor).join();
assertEquals(State.ACTIVE, state);
// 4. just submit a new scale. don't let it run. this should create an epoch transition. state should still be active
streamStore.submitScale(scope, stream, Lists.newArrayList(1L), Lists.newArrayList(new AbstractMap.SimpleEntry<>(0.5, 0.75), new AbstractMap.SimpleEntry<>(0.75, 1.0)), System.currentTimeMillis(), null, null, executor).join();
// 5. commit on old epoch. this should roll over.
assertTrue(Futures.await(commitRequestHandler.processEvent(new CommitEvent(scope, stream, txnData.getEpoch()))));
TxnStatus txnStatus = streamStore.transactionStatus(scope, stream, txnIdOldEpoch, null, executor).join();
assertEquals(TxnStatus.COMMITTED, txnStatus);
// 6. run scale against old record but with manual scale flag set to true. This should be migrated to new epoch and processed.
requestHandler.process(new ScaleOpEvent(scope, stream, Lists.newArrayList(1L), Lists.newArrayList(new AbstractMap.SimpleEntry<>(0.5, 0.75), new AbstractMap.SimpleEntry<>(0.75, 1.0)), true, System.currentTimeMillis(), System.currentTimeMillis()), () -> false).join();
state = streamStore.getState(scope, stream, true, null, executor).join();
assertEquals(State.ACTIVE, state);
EpochRecord epoch = streamStore.getActiveEpoch(scope, stream, null, true, executor).join();
assertEquals(4, epoch.getEpoch());
}
use of io.pravega.controller.store.stream.VersionedTransactionData in project pravega by pravega.
the class ScaleRequestHandlerTest method testScaleWithTransactionRequest.
@Test(timeout = 30000)
public void testScaleWithTransactionRequest() throws InterruptedException {
EventWriterMock writer = new EventWriterMock();
streamMetadataTasks.setRequestEventWriter(writer);
ScaleOperationTask scaleRequestHandler = new ScaleOperationTask(streamMetadataTasks, streamStore, executor);
StreamRequestHandler requestHandler = new StreamRequestHandler(null, scaleRequestHandler, null, null, null, null, null, null, null, streamStore, null, executor);
CommitRequestHandler commitRequestHandler = new CommitRequestHandler(streamStore, streamMetadataTasks, streamTransactionMetadataTasks, bucketStore, executor);
// 1 create transaction on old epoch and set it to committing
UUID txnIdOldEpoch = streamStore.generateTransactionId(scope, stream, null, executor).join();
VersionedTransactionData txnData = streamStore.createTransaction(scope, stream, txnIdOldEpoch, 10000, 10000, null, executor).join();
streamStore.sealTransaction(scope, stream, txnData.getId(), true, Optional.empty(), "", Long.MIN_VALUE, null, executor).join();
EpochRecord epochZero = streamStore.getActiveEpoch(scope, stream, null, true, executor).join();
assertEquals(0, epochZero.getEpoch());
// 2. start scale
requestHandler.process(new ScaleOpEvent(scope, stream, Lists.newArrayList(0L, 1L, 2L), Lists.newArrayList(new AbstractMap.SimpleEntry<>(0.0, 1.0)), false, System.currentTimeMillis(), System.currentTimeMillis()), () -> false).join();
// 3. verify that scale is complete
State state = streamStore.getState(scope, stream, true, null, executor).join();
assertEquals(State.ACTIVE, state);
EpochRecord epochOne = streamStore.getActiveEpoch(scope, stream, null, true, executor).join();
assertEquals(1, epochOne.getEpoch());
// 4. create transaction -> verify that this is created on new epoch
UUID txnIdNewEpoch = streamStore.generateTransactionId(scope, stream, null, executor).join();
VersionedTransactionData txnDataNew = streamStore.createTransaction(scope, stream, txnIdNewEpoch, 10000, 10000, null, executor).join();
streamStore.sealTransaction(scope, stream, txnDataNew.getId(), true, Optional.empty(), "", Long.MIN_VALUE, null, executor).join();
// 5. commit on old epoch. this should roll over
assertTrue(Futures.await(commitRequestHandler.processEvent(new CommitEvent(scope, stream, txnData.getEpoch()))));
TxnStatus txnStatus = streamStore.transactionStatus(scope, stream, txnIdOldEpoch, null, executor).join();
assertEquals(TxnStatus.COMMITTED, txnStatus);
EpochRecord epochTwo = streamStore.getEpoch(scope, stream, 2, null, executor).join();
EpochRecord epochThree = streamStore.getEpoch(scope, stream, 3, null, executor).join();
assertEquals(0, epochTwo.getReferenceEpoch());
assertEquals(epochZero.getSegments().size(), epochTwo.getSegments().size());
assertEquals(epochZero.getSegments().stream().map(x -> NameUtils.getSegmentNumber(x.segmentId())).collect(Collectors.toSet()), epochTwo.getSegments().stream().map(x -> NameUtils.getSegmentNumber(x.segmentId())).collect(Collectors.toSet()));
assertEquals(1, epochThree.getReferenceEpoch());
assertEquals(epochOne.getSegments().size(), epochThree.getSegments().size());
assertEquals(epochOne.getSegments().stream().map(x -> NameUtils.getSegmentNumber(x.segmentId())).collect(Collectors.toSet()), epochThree.getSegments().stream().map(x -> NameUtils.getSegmentNumber(x.segmentId())).collect(Collectors.toSet()));
EpochRecord activeEpoch = streamStore.getActiveEpoch(scope, stream, null, true, executor).join();
assertEquals(epochThree, activeEpoch);
// 6. commit on new epoch. This should happen on duplicate of new epoch successfully
assertTrue(Futures.await(commitRequestHandler.processEvent(new CommitEvent(scope, stream, txnDataNew.getEpoch()))));
txnStatus = streamStore.transactionStatus(scope, stream, txnIdNewEpoch, null, executor).join();
assertEquals(TxnStatus.COMMITTED, txnStatus);
activeEpoch = streamStore.getActiveEpoch(scope, stream, null, true, executor).join();
assertEquals(epochThree, activeEpoch);
}
Aggregations