use of com.palantir.lock.v2.StartIdentifiedAtlasDbTransactionResponse in project atlasdb by palantir.
the class TransactionStarterTest method shouldDeriveStartTransactionResponseFromBatchedResponse_multipleTransactions.
@Test
public void shouldDeriveStartTransactionResponseFromBatchedResponse_multipleTransactions() {
ConjureStartTransactionsResponse batchResponse = StartTransactionsTestUtils.getStartTransactionResponse(40, 3);
when(lockLeaseService.startTransactionsWithWatches(version, 3)).thenReturn(batchResponse);
List<StartIdentifiedAtlasDbTransactionResponse> responses = requestSingularBatches(3);
assertThat(responses).satisfies(StartTransactionsTestUtils::assertThatStartTransactionResponsesAreUnique).hasSize(3).allSatisfy(startTxnResponse -> assertDerivableFromBatchedResponse(startTxnResponse, batchResponse));
}
use of com.palantir.lock.v2.StartIdentifiedAtlasDbTransactionResponse in project atlasdb by palantir.
the class MultiClientTransactionStarter method getResponseHandlers.
private static Map<Namespace, ResponseHandler> getResponseHandlers(List<BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>>> batch) {
Map<Namespace, ResponseHandler> responseHandlers = new HashMap<>();
for (BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>> element : batch) {
NamespaceAndRequestParams requestParams = element.argument();
Namespace namespace = requestParams.namespace();
responseHandlers.computeIfAbsent(namespace, _unused -> new ResponseHandler(requestParams.params().lockCleanupService(), requestParams.params().cache())).addPendingFuture(SettableResponse.of(requestParams.params().numTransactions(), element.result()));
}
return responseHandlers;
}
use of com.palantir.lock.v2.StartIdentifiedAtlasDbTransactionResponse in project atlasdb by palantir.
the class SnapshotTransactionManager method startTransactions.
@Override
public List<OpenTransaction> startTransactions(List<? extends PreCommitCondition> conditions) {
if (conditions.isEmpty()) {
return ImmutableList.of();
}
final List<StartIdentifiedAtlasDbTransactionResponse> responses;
try {
responses = timelockService.startIdentifiedAtlasDbTransactionBatch(conditions.size());
} catch (StartTransactionFailedException e) {
throw new TransactionFailedRetriableException("Failed to start a batch of transactions", e);
}
Preconditions.checkState(conditions.size() == responses.size(), "Different number of responses and conditions");
try {
long immutableTs = responses.stream().mapToLong(response -> response.immutableTimestamp().getImmutableTimestamp()).max().getAsLong();
recordImmutableTimestamp(immutableTs);
cleaner.punch(responses.get(0).startTimestampAndPartition().timestamp());
List<OpenTransaction> transactions = Streams.zip(responses.stream(), conditions.stream(), (response, condition) -> {
LockToken immutableTsLock = response.immutableTimestamp().getLock();
Supplier<Long> startTimestampSupplier = Suppliers.ofInstance(response.startTimestampAndPartition().timestamp());
Transaction transaction = createTransaction(immutableTs, startTimestampSupplier, immutableTsLock, condition);
transaction.onSuccess(() -> lockWatchManager.onTransactionCommit(transaction.getTimestamp()));
return new OpenTransactionImpl(transaction, immutableTsLock);
}).collect(Collectors.toList());
openTransactionCounter.inc(transactions.size());
return transactions;
} catch (Throwable t) {
responses.forEach(response -> lockWatchManager.removeTransactionStateFromCache(response.startTimestampAndPartition().timestamp()));
timelockService.tryUnlock(responses.stream().map(response -> response.immutableTimestamp().getLock()).collect(Collectors.toSet()));
throw Throwables.rewrapAndThrowUncheckedException(t);
}
}
use of com.palantir.lock.v2.StartIdentifiedAtlasDbTransactionResponse 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.lock.v2.StartIdentifiedAtlasDbTransactionResponse 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));
}
});
}
Aggregations