use of com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse in project atlasdb by palantir.
the class SnapshotTransactionTest method startTransactionWithWatches.
private ConjureStartTransactionsResponse startTransactionWithWatches() {
ConjureStartTransactionsResponse conjureResponse = inMemoryTimeLockRule.get().getLockLeaseService().startTransactionsWithWatches(Optional.empty(), 1);
Set<Long> startTimestamps = conjureResponse.getTimestamps().stream().boxed().collect(Collectors.toSet());
inMemoryTimeLockRule.getLockWatchManager().getCache().processStartTransactionsUpdate(startTimestamps, conjureResponse.getLockWatchUpdate());
return conjureResponse;
}
use of com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse in project atlasdb by palantir.
the class SnapshotTransactionTest method getSortedColumnsThrowsIfLockIsLostMidway.
@Test
public void getSortedColumnsThrowsIfLockIsLostMidway() {
List<byte[]> rows = LongStream.range(0, 10).mapToObj(PtBytes::toBytes).collect(Collectors.toList());
List<Cell> cells = rows.stream().map(row -> Cell.create(row, COL_A)).collect(Collectors.toList());
putCellsInTable(cells, TABLE_SWEPT_THOROUGH);
ConjureStartTransactionsResponse conjureResponse = startTransactionWithWatches();
LockImmutableTimestampResponse res = conjureResponse.getImmutableTimestamp();
long transactionTs = conjureResponse.getTimestamps().start();
Transaction transaction = getSnapshotTransactionWith(timelockService, () -> transactionTs, res, PreCommitConditions.NO_OP, true);
int batchHint = 5;
Iterator<Map.Entry<Cell, byte[]>> sortedColumns = transaction.getSortedColumns(TABLE_SWEPT_THOROUGH, rows, BatchColumnRangeSelection.create(PtBytes.EMPTY_BYTE_ARRAY, PtBytes.EMPTY_BYTE_ARRAY, batchHint));
assertThat(sortedColumns.next().getKey()).isEqualTo(cells.get(0));
// lock lost after getting first batch
timelockService.unlock(ImmutableSet.of(res.getLock()));
// should still be able to get all but last element of the elements for the first batch;
// next batch is preemptively fetched when last element of curr batch is retrieved
List<Cell> retrievedEntries = IntStream.range(1, batchHint - 1).mapToObj(_unused -> sortedColumns.next().getKey()).collect(Collectors.toList());
assertThat(retrievedEntries).hasSameElementsAs(cells.subList(1, batchHint - 1));
// should throw while fetching the next batch
assertThatThrownBy(sortedColumns::next).isInstanceOf(TransactionLockTimeoutException.class);
}
use of com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse in project atlasdb by palantir.
the class SnapshotTransactionTest method commitDoesNotThrowIfAlreadySuccessfullyCommitted.
@Test
public void commitDoesNotThrowIfAlreadySuccessfullyCommitted() {
final Cell cell = Cell.create(PtBytes.toBytes("row1"), PtBytes.toBytes("column1"));
TimelockService spiedTimeLockService = spy(timelockService);
ConjureStartTransactionsResponse conjureResponse = startTransactionWithWatches();
LockImmutableTimestampResponse res = conjureResponse.getImmutableTimestamp();
long transactionTs = conjureResponse.getTimestamps().start();
Transaction snapshot = getSnapshotTransactionWith(spiedTimeLockService, () -> transactionTs, res, PreCommitConditions.NO_OP);
when(spiedTimeLockService.getFreshTimestamp()).thenReturn(transactionTs + 1);
doReturn(transactionTs + 1).when(spiedTimeLockService).getCommitTimestamp(anyLong(), any());
// forcing to try to commit a transaction that is already committed
transactionService.putUnlessExists(transactionTs, spiedTimeLockService.getFreshTimestamp());
snapshot.put(TABLE, ImmutableMap.of(cell, PtBytes.toBytes("value")));
snapshot.commit();
spiedTimeLockService.unlock(Collections.singleton(res.getLock()));
}
use of com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse in project atlasdb by palantir.
the class MultiClientTransactionStarterTest method servesRequestsAsSoonAsResponseIsReceived.
@Test
public void servesRequestsAsSoonAsResponseIsReceived() {
Namespace namespace = Namespace.of("Test" + UUID.randomUUID());
UUID requestorId = UUID.randomUUID();
BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>> requestToBeServed = batchElementForNamespace(namespace, 1);
BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>> requestNotToBeServed = batchElementForNamespace(namespace, PARTITIONED_TIMESTAMPS_LIMIT_PER_SERVER_CALL * 5);
ImmutableList<BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>>> requests = ImmutableList.of(requestToBeServed, requestNotToBeServed);
Map<Namespace, ConjureStartTransactionsResponse> responseMap = startTransactionsResponse(requests, requestorId);
when(timelockService.startTransactions(any())).thenReturn(responseMap).thenThrow(EXCEPTION);
assertThatThrownBy(() -> processBatch(timelockService, requestorId, requests)).isEqualTo(EXCEPTION);
// assert first request is served even if server throws on next request
assertSanityOfRequestBatch(ImmutableList.of(requestToBeServed), ImmutableMap.of(namespace, ImmutableList.of(responseMap.get(namespace))));
assertThat(requestNotToBeServed.result().isDone()).isFalse();
LockCleanupService relevantLockCleanupService = LOCK_CLEANUP_SERVICE_MAP.get(namespace);
verify(relevantLockCleanupService).refreshLockLeases(any());
verify(relevantLockCleanupService).unlock(any());
/*
* For one space, all requests are accumulated, and we attempt to fetch as many respones as possible from the
* server. Concretely, the queue here contains 25 demands for a response. The first one succeeds, but the
* next four fail (and each batch size is five), and thus we get four calls to clean up.
*/
verify(NAMESPACE_CACHE_MAP.get(namespace), times(4)).removeTransactionStateFromCache(anyLong());
}
use of com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse in project atlasdb by palantir.
the class MultiClientTransactionStarterTest method shouldNotFreeResourcesIfRequestIsServed.
@Test
public void shouldNotFreeResourcesIfRequestIsServed() {
Namespace alpha = Namespace.of("alpha" + UUID.randomUUID());
Namespace beta = Namespace.of("beta" + UUID.randomUUID());
BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>> requestForAlpha = batchElementForNamespace(alpha, PARTITIONED_TIMESTAMPS_LIMIT_PER_SERVER_CALL - 1);
BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>> requestForBeta = batchElementForNamespace(beta, PARTITIONED_TIMESTAMPS_LIMIT_PER_SERVER_CALL * 5);
UUID requestorId = UUID.randomUUID();
List<BatchElement<NamespaceAndRequestParams, List<StartIdentifiedAtlasDbTransactionResponse>>> requests = ImmutableList.of(requestForAlpha, requestForBeta);
Map<Namespace, ConjureStartTransactionsResponse> responseMap = startTransactionsResponse(requests, requestorId);
when(timelockService.startTransactions(any())).thenReturn(responseMap).thenThrow(EXCEPTION);
assertThatThrownBy(() -> processBatch(timelockService, requestorId, requests)).isEqualTo(EXCEPTION);
// assert requests made by client alpha are served
assertSanityOfRequestBatch(ImmutableList.of(requestForAlpha), ImmutableMap.of(alpha, ImmutableList.of(responseMap.get(alpha))));
verify(LOCK_CLEANUP_SERVICE_MAP.get(alpha), never()).unlock(any());
verify(LOCK_CLEANUP_SERVICE_MAP.get(beta)).refreshLockLeases(any());
verify(LOCK_CLEANUP_SERVICE_MAP.get(beta)).unlock(any());
verify(NAMESPACE_CACHE_MAP.get(alpha), never()).removeTransactionStateFromCache(anyLong());
// The size of each batch is 5 here, and thus for a single batch we need to clean up five times
verify(NAMESPACE_CACHE_MAP.get(beta), times(5)).removeTransactionStateFromCache(anyLong());
}
Aggregations