use of com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse in project atlasdb by palantir.
the class SnapshotTransactionTest method commitThrowsIfRolledBackAtCommitTime_expiredLocks.
@Test
public void commitThrowsIfRolledBackAtCommitTime_expiredLocks() {
final Cell cell = Cell.create(PtBytes.toBytes("row1"), PtBytes.toBytes("column1"));
TimelockService timelockService = spy(inMemoryTimeLockRule.getLegacyTimelockService());
// expire the locks when the pre-commit check happens - this is guaranteed to be after we've written the data
PreCommitCondition condition = unused -> doReturn(ImmutableSet.of()).when(timelockService).refreshLockLeases(any());
ConjureStartTransactionsResponse conjureResponse = startTransactionWithWatches();
LockImmutableTimestampResponse res = conjureResponse.getImmutableTimestamp();
long transactionTs = conjureResponse.getTimestamps().start();
Transaction snapshot = getSnapshotTransactionWith(timelockService, () -> transactionTs, res, condition);
// simulate roll back at commit time
transactionService.putUnlessExists(snapshot.getTimestamp(), TransactionConstants.FAILED_COMMIT_TS);
snapshot.put(TABLE, ImmutableMap.of(cell, PtBytes.toBytes("value")));
assertThatExceptionOfType(TransactionLockTimeoutException.class).isThrownBy(snapshot::commit);
timelockService.unlock(ImmutableSet.of(res.getLock()));
TransactionOutcomeMetricsAssert.assertThat(transactionOutcomeMetrics).hasFailedCommits(1).hasLocksExpired(1);
}
use of com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse in project atlasdb by palantir.
the class MultiClientTransactionStarterTest method shouldNotFreeResourcesWithinNamespaceIfRequestIsServed.
@Test
public void shouldNotFreeResourcesWithinNamespaceIfRequestIsServed() {
Namespace omega = Namespace.of("omega" + UUID.randomUUID());
BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>> requestForOmega = batchElementForNamespace(omega, PARTITIONED_TIMESTAMPS_LIMIT_PER_SERVER_CALL - 1);
BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>> secondRequestForOmega = batchElementForNamespace(omega, 2);
UUID requestorId = UUID.randomUUID();
List<BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>>> requests = ImmutableList.of(requestForOmega, secondRequestForOmega);
Map<Namespace, ConjureStartTransactionsResponse> responseMap = startTransactionsResponse(requests, requestorId);
when(timelockService.startTransactions(any())).thenReturn(responseMap).thenThrow(EXCEPTION);
assertThatThrownBy(() -> processBatch(timelockService, requestorId, requests)).isEqualTo(EXCEPTION);
// assert the first request made by client omega is served
assertSanityOfRequestBatch(ImmutableList.of(requestForOmega), ImmutableMap.of(omega, ImmutableList.of(responseMap.get(omega))));
@SuppressWarnings({ "unchecked", "rawtypes" }) ArgumentCaptor<Set<LockToken>> refreshArgumentCaptor = (ArgumentCaptor<Set<LockToken>>) ArgumentCaptor.forClass((Class) Set.class);
verify(LOCK_CLEANUP_SERVICE_MAP.get(omega)).refreshLockLeases(refreshArgumentCaptor.capture());
verify(LOCK_CLEANUP_SERVICE_MAP.get(omega)).unlock(eq(Collections.emptySet()));
verify(NAMESPACE_CACHE_MAP.get(omega)).removeTransactionStateFromCache(anyLong());
Set<LockToken> refreshedTokens = refreshArgumentCaptor.getValue();
LockToken tokenShare = Futures.getUnchecked(requestForOmega.result()).get(0).immutableTimestamp().getLock();
assertThat(tokenShare).isInstanceOf(LockTokenShare.class).satisfies(token -> {
LockTokenShare share = ((LockTokenShare) token);
assertThat(share.sharedLockToken()).isIn(refreshedTokens);
});
}
use of com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse in project atlasdb by palantir.
the class MultiClientTransactionStarterTest method setupServiceAndAssertSanity.
private void setupServiceAndAssertSanity(List<BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>>> requestsForClients) {
UUID requestorId = UUID.randomUUID();
Map<Namespace, List<ConjureStartTransactionsResponse>> responseMap = new HashMap<>();
when(timelockService.startTransactions(any())).thenAnswer(invocation -> {
Map<Namespace, ConjureStartTransactionsResponse> responses = startTransactions(invocation.getArgument(0), getLowestTs());
responses.forEach((namespace, response) -> responseMap.computeIfAbsent(namespace, _u -> new ArrayList<>()).add(response));
return responses;
});
processBatch(timelockService, requestorId, requestsForClients);
// assertions on responses
assertSanityOfRequestBatch(requestsForClients, responseMap);
}
use of com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse in project atlasdb by palantir.
the class MultiClientTransactionStarterTest method assertSanityOfRequestBatch.
private void assertSanityOfRequestBatch(List<BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>>> requestsForClients, Map<Namespace, List<ConjureStartTransactionsResponse>> responseMap) {
assertCompletedWithCorrectNumberOfTransactions(requestsForClients);
Map<Namespace, List<BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>>>> partitionedResponses = requestsForClients.stream().collect(Collectors.groupingBy(e -> e.argument().namespace()));
responseMap.forEach((namespace, responses) -> {
int startInd = 0;
List<StartIdentifiedAtlasDbTransactionResponse> startedTransactions = partitionedResponses.get(namespace).stream().map(response -> Futures.getUnchecked(response.result())).flatMap(Collection::stream).collect(Collectors.toList());
for (ConjureStartTransactionsResponse conjureResponse : responses) {
int toIndex = Math.min(startInd + conjureResponse.getTimestamps().count(), startedTransactions.size());
List<StartIdentifiedAtlasDbTransactionResponse> responseList = startedTransactions.subList(startInd, toIndex);
startInd = toIndex;
assertThat(responseList).satisfies(StartTransactionsTestUtils::assertThatStartTransactionResponsesAreUnique).allSatisfy(startTxnResponse -> StartTransactionsTestUtils.assertDerivableFromBatchedResponse(startTxnResponse, conjureResponse));
}
});
}
use of com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse in project atlasdb by palantir.
the class TimestampCorroboratingTimelockServiceTest method failsUnderConflictingMixedOperations.
@Test
public void failsUnderConflictingMixedOperations() {
ConjureStartTransactionsResponse startTransactionsResponse = makeResponse(1L, 1);
when(rawTimelockService.startTransactions(startTransactionsRequest)).thenReturn(startTransactionsResponse);
when(rawTimelockService.getFreshTimestamps(any())).thenReturn(getFreshTimestampsResponse(1L, 2L));
timelockService.startTransactions(startTransactionsRequest);
assertThrowsClocksWentBackwardsException(() -> getFreshTimestamps(2));
assertThat(timelockService.getTimestampBounds().boundFromTransactions().lowerBoundForNextRequest()).isEqualTo(1L);
assertThat(timelockService.getTimestampBounds().boundFromTransactions().operationType()).isEqualTo(OperationType.TRANSACTION);
assertThat(timelockService.getTimestampBounds().boundFromFreshTimestamps().lowerBoundForNextRequest()).isEqualTo(Long.MIN_VALUE);
verify(callback).run();
}
Aggregations