Search in sources :

Example 6 with BatchElement

use of com.palantir.atlasdb.autobatch.BatchElement 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());
}
Also used : StartIdentifiedAtlasDbTransactionResponse(com.palantir.lock.v2.StartIdentifiedAtlasDbTransactionResponse) ConjureStartTransactionsResponse(com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse) NamespaceAndRequestParams(com.palantir.lock.client.MultiClientTransactionStarter.NamespaceAndRequestParams) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) BatchElement(com.palantir.atlasdb.autobatch.BatchElement) UUID(java.util.UUID) Namespace(com.palantir.atlasdb.timelock.api.Namespace) Test(org.junit.Test)

Example 7 with BatchElement

use of com.palantir.atlasdb.autobatch.BatchElement 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());
}
Also used : StartIdentifiedAtlasDbTransactionResponse(com.palantir.lock.v2.StartIdentifiedAtlasDbTransactionResponse) ConjureStartTransactionsResponse(com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse) NamespaceAndRequestParams(com.palantir.lock.client.MultiClientTransactionStarter.NamespaceAndRequestParams) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) BatchElement(com.palantir.atlasdb.autobatch.BatchElement) UUID(java.util.UUID) Namespace(com.palantir.atlasdb.timelock.api.Namespace) Test(org.junit.Test)

Example 8 with BatchElement

use of com.palantir.atlasdb.autobatch.BatchElement 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;
}
Also used : DisruptorFuture(com.palantir.atlasdb.autobatch.DisruptorAutobatcher.DisruptorFuture) ConjureLockRequests.toConjure(com.palantir.lock.client.ConjureLockRequests.toConjure) HashMap(java.util.HashMap) BatchElement(com.palantir.atlasdb.autobatch.BatchElement) ConjureStartTransactionsResponse(com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse) ConjureStartTransactionsRequest(com.palantir.atlasdb.timelock.api.ConjureStartTransactionsRequest) ImmutableList(com.google.common.collect.ImmutableList) Value(org.immutables.value.Value) Duration(java.time.Duration) Map(java.util.Map) LockWatchCache(com.palantir.lock.watch.LockWatchCache) DisruptorAutobatcher(com.palantir.atlasdb.autobatch.DisruptorAutobatcher) AtlasFutures(com.palantir.atlasdb.futures.AtlasFutures) Autobatchers(com.palantir.atlasdb.autobatch.Autobatchers) KeyedStream(com.palantir.common.streams.KeyedStream) UUID(java.util.UUID) Namespace(com.palantir.atlasdb.timelock.api.Namespace) Maps(com.google.common.collect.Maps) Collectors(java.util.stream.Collectors) Consumer(java.util.function.Consumer) List(java.util.List) StartIdentifiedAtlasDbTransactionResponse(com.palantir.lock.v2.StartIdentifiedAtlasDbTransactionResponse) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Queue(java.util.Queue) ArrayDeque(java.util.ArrayDeque) Preconditions(com.palantir.logsafe.Preconditions) HashMap(java.util.HashMap) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) Namespace(com.palantir.atlasdb.timelock.api.Namespace)

Example 9 with BatchElement

use of com.palantir.atlasdb.autobatch.BatchElement 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);
    });
}
Also used : Set(java.util.Set) ArgumentCaptor(org.mockito.ArgumentCaptor) LockToken(com.palantir.lock.v2.LockToken) BatchElement(com.palantir.atlasdb.autobatch.BatchElement) Namespace(com.palantir.atlasdb.timelock.api.Namespace) StartIdentifiedAtlasDbTransactionResponse(com.palantir.lock.v2.StartIdentifiedAtlasDbTransactionResponse) ConjureStartTransactionsResponse(com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse) NamespaceAndRequestParams(com.palantir.lock.client.MultiClientTransactionStarter.NamespaceAndRequestParams) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) UUID(java.util.UUID) Test(org.junit.Test)

Example 10 with BatchElement

use of com.palantir.atlasdb.autobatch.BatchElement 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));
        }
    });
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) DisruptorFuture(com.palantir.atlasdb.autobatch.DisruptorAutobatcher.DisruptorFuture) IntStream(java.util.stream.IntStream) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) SafeIllegalStateException(com.palantir.logsafe.exceptions.SafeIllegalStateException) HashMap(java.util.HashMap) Mockito.spy(org.mockito.Mockito.spy) BatchElement(com.palantir.atlasdb.autobatch.BatchElement) ConjureStartTransactionsResponse(com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse) ArrayList(java.util.ArrayList) ConjureStartTransactionsRequest(com.palantir.atlasdb.timelock.api.ConjureStartTransactionsRequest) ArgumentCaptor(org.mockito.ArgumentCaptor) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) ImmutableList(com.google.common.collect.ImmutableList) Map(java.util.Map) LockWatchCache(com.palantir.lock.watch.LockWatchCache) ImmutableMap(com.google.common.collect.ImmutableMap) NamespaceAndRequestParams(com.palantir.lock.client.MultiClientTransactionStarter.NamespaceAndRequestParams) KeyedStream(com.palantir.common.streams.KeyedStream) LockToken(com.palantir.lock.v2.LockToken) Collection(java.util.Collection) Set(java.util.Set) Mockito.times(org.mockito.Mockito.times) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) UUID(java.util.UUID) Namespace(com.palantir.atlasdb.timelock.api.Namespace) Collectors(java.util.stream.Collectors) MultiClientTransactionStarter.processBatch(com.palantir.lock.client.MultiClientTransactionStarter.processBatch) Mockito.verify(org.mockito.Mockito.verify) Mockito.never(org.mockito.Mockito.never) Futures(com.google.common.util.concurrent.Futures) List(java.util.List) RequestParams(com.palantir.lock.client.MultiClientTransactionStarter.RequestParams) StartIdentifiedAtlasDbTransactionResponse(com.palantir.lock.v2.StartIdentifiedAtlasDbTransactionResponse) LockWatchCacheImpl(com.palantir.lock.watch.LockWatchCacheImpl) Collections(java.util.Collections) Mockito.mock(org.mockito.Mockito.mock) StartIdentifiedAtlasDbTransactionResponse(com.palantir.lock.v2.StartIdentifiedAtlasDbTransactionResponse) ConjureStartTransactionsResponse(com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse) NamespaceAndRequestParams(com.palantir.lock.client.MultiClientTransactionStarter.NamespaceAndRequestParams) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) Namespace(com.palantir.atlasdb.timelock.api.Namespace)

Aggregations

BatchElement (com.palantir.atlasdb.autobatch.BatchElement)12 ImmutableList (com.google.common.collect.ImmutableList)11 List (java.util.List)11 Test (org.junit.Test)10 Namespace (com.palantir.atlasdb.timelock.api.Namespace)7 SafeIllegalStateException (com.palantir.logsafe.exceptions.SafeIllegalStateException)7 UUID (java.util.UUID)7 Collectors (java.util.stream.Collectors)7 ImmutableMap (com.google.common.collect.ImmutableMap)6 IntStream (java.util.stream.IntStream)6 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)6 Assertions.assertThatThrownBy (org.assertj.core.api.Assertions.assertThatThrownBy)6 Mockito.mock (org.mockito.Mockito.mock)6 Mockito.times (org.mockito.Mockito.times)6 Mockito.verify (org.mockito.Mockito.verify)6 Mockito.when (org.mockito.Mockito.when)6 DisruptorAutobatcher (com.palantir.atlasdb.autobatch.DisruptorAutobatcher)5 ConjureStartTransactionsResponse (com.palantir.atlasdb.timelock.api.ConjureStartTransactionsResponse)5 StartIdentifiedAtlasDbTransactionResponse (com.palantir.lock.v2.StartIdentifiedAtlasDbTransactionResponse)5 ArrayList (java.util.ArrayList)5