Search in sources :

Example 1 with SampleServiceAsync

use of com.palantir.dialogue.example.SampleServiceAsync in project dialogue by palantir.

the class DialogueClientsIntegrationTest method testSticky.

private <F> void testSticky(BiFunction<ReloadingFactory, String, F> factoryFactory, BiFunction<F, Class<SampleServiceAsync>, SampleServiceAsync> clientFactory) {
    List<StringToVoidRequestPath> requestPaths = Collections.synchronizedList(new ArrayList<>());
    int maxConcurrentRequestsPerServer = 10;
    Map<String, Integer> activeRequestsPerServer = new ConcurrentHashMap<>();
    undertowHandler = exchange -> {
        String requestPath = exchange.getRequestPath();
        StringToVoidRequestPath path = parse(requestPath);
        String server = path.requestPath();
        try {
            int activeRequests = activeRequestsPerServer.compute(server, (_ignore, activeRequests1) -> {
                if (activeRequests1 == null) {
                    return 1;
                } else {
                    return activeRequests1 + 1;
                }
            });
            if (activeRequests > maxConcurrentRequestsPerServer) {
                exchange.setStatusCode(200);
            } else {
                exchange.setStatusCode(429);
            }
        } finally {
            activeRequestsPerServer.compute(server, (_ignore, activeRequests12) -> {
                Preconditions.checkNotNull(activeRequests12, "activeRequests");
                Preconditions.checkState(activeRequests12 > 0, "activeRequests");
                return activeRequests12 - 1;
            });
            requestPaths.add(path);
        }
    };
    SettableRefreshable<ServicesConfigBlock> refreshable = Refreshable.create(ServicesConfigBlock.builder().from(scb).putServices(FOO_SERVICE, threeFoos).build());
    DialogueClients.ReloadingFactory factory = DialogueClients.create(refreshable).withUserAgent(TestConfigurations.AGENT);
    F stickyChannels = factoryFactory.apply(factory, FOO_SERVICE);
    int numClients = 3;
    int numRequestPerClient = 1000;
    List<ListenableFuture<?>> requests = new ArrayList<>();
    for (int i = 0; i < numClients; i++) {
        SampleServiceAsync client = clientFactory.apply(stickyChannels, SampleServiceAsync.class);
        String clientId = Integer.toString(i);
        IntStream.range(0, numRequestPerClient).forEach(_ignore -> requests.add(client.stringToVoid(clientId)));
    }
    assertThat(Futures.whenAllComplete(requests).run(() -> {
    }, MoreExecutors.directExecutor())).succeedsWithin(Duration.ofMinutes(1));
    assertThat(requestPaths).hasSizeGreaterThanOrEqualTo(numClients * numRequestPerClient);
    Set<StringToVoidRequestPath> uniquePaths = new HashSet<>(requestPaths);
    assertThat(uniquePaths).hasSize(numClients);
    // *I think* this technically has a chance to flake, but let's see how it goes. I am trying to make sure the
    // requests are actually being pinned and not just because all the requests went to a single node.
    assertThat(uniquePaths.stream().map(StringToVoidRequestPath::server)).hasSizeGreaterThanOrEqualTo(2);
    List<String> clientIds = uniquePaths.stream().map(StringToVoidRequestPath::client).collect(Collectors.toList());
    assertThat(clientIds).containsExactlyInAnyOrder("0", "1", "2");
}
Also used : ServicesConfigBlock(com.palantir.conjure.java.api.config.service.ServicesConfigBlock) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) ReloadingFactory(com.palantir.dialogue.clients.DialogueClients.ReloadingFactory) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SampleServiceAsync(com.palantir.dialogue.example.SampleServiceAsync) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) DialogueClients(com.palantir.dialogue.clients.DialogueClients) HashSet(java.util.HashSet)

Example 2 with SampleServiceAsync

use of com.palantir.dialogue.example.SampleServiceAsync in project dialogue by palantir.

the class StickyEndpointChannelsTest method sticky_channel_stays_put_despite_503s.

@Test
void sticky_channel_stays_put_despite_503s() {
    StickyEndpointChannels channels = builder().channels(ImmutableList.of(miniServer("one", serve204), miniServer("two", serve204), miniServer("three", immediate503))).build();
    SampleServiceAsync async1 = SampleServiceAsync.of(channels.get(), runtime);
    async1.voidToVoid();
    async1.getMyAlias();
    async1.getOptionalBinary();
    assertThat(responses).describedAs("We chose channel [three] randomly, and stay pinned so that a transaction has the best " + "chance of completing").containsExactly("[three] 503", "[three] 503", "[three] 503");
    requests.clear();
    for (int i = 0; i < 200; i++) {
        SampleServiceAsync async = SampleServiceAsync.of(channels.get(), runtime);
        async.voidToVoid();
        async.getMyAlias();
        async.getOptionalBinary();
    }
    assertThat(requests).describedAs("The BalancedScoreTracker understands that channel [three] is " + "bad (returning 503s), so 200 more 'transactions' are routed to [one] or [two]").allSatisfy(string -> assertThat(string).doesNotContain("[three]"));
}
Also used : SampleServiceAsync(com.palantir.dialogue.example.SampleServiceAsync) Test(org.junit.jupiter.api.Test)

Example 3 with SampleServiceAsync

use of com.palantir.dialogue.example.SampleServiceAsync in project dialogue by palantir.

the class StickyEndpointChannelsTest method sticky_channel_stays_put_despite_429s.

@Test
void sticky_channel_stays_put_despite_429s() {
    StickyEndpointChannels channels = builder().channels(ImmutableList.of(miniServer("one", serve204), miniServer("two", serve204), miniServer("three", immediate429))).build();
    SampleServiceAsync async1 = SampleServiceAsync.of(channels.get(), runtime);
    async1.voidToVoid();
    async1.getMyAlias();
    async1.getOptionalBinary();
    assertThat(responses).describedAs("We chose channel [three] randomly, and stay pinned so that a transaction has the best " + "chance of completing").containsExactly("[three] 429", "[three] 429", "[three] 429");
    requests.clear();
    for (int i = 0; i < 2; i++) {
        SampleServiceAsync async = SampleServiceAsync.of(channels.get(), runtime);
        async.voidToVoid();
        async.getMyAlias();
        async.getOptionalBinary();
    }
    assertThat(requests).describedAs("The BalancedScoreTracker understands that channel [three] is " + "bad (returning 503s), so 200 more 'transactions' are routed to [one] or [two]").allSatisfy(string -> assertThat(string).doesNotContain("[three]"));
}
Also used : SampleServiceAsync(com.palantir.dialogue.example.SampleServiceAsync) Test(org.junit.jupiter.api.Test)

Example 4 with SampleServiceAsync

use of com.palantir.dialogue.example.SampleServiceAsync in project dialogue by palantir.

the class StickyEndpointChannelsTest method all_calls_on_a_sticky_channel_go_to_one_host.

@Test
void all_calls_on_a_sticky_channel_go_to_one_host() {
    StickyEndpointChannels channels = builder().channels(ImmutableList.of(miniServer("one", serve204), miniServer("two", serve204), miniServer("three", serve204))).build();
    Channel sticky1 = channels.get();
    SampleServiceAsync async1 = SampleServiceAsync.of(sticky1, runtime);
    async1.voidToVoid();
    async1.getMyAlias();
    async1.getOptionalBinary();
    SampleServiceBlocking blocking1 = SampleServiceBlocking.of(sticky1, runtime);
    blocking1.voidToVoid();
    blocking1.voidToVoid();
    assertThat(requests).describedAs("All requests should go to the same randomly chosen host, in this case 'three'").allSatisfy(string -> assertThat(string).startsWith("[three]"));
    requests.clear();
    Channel sticky2 = channels.get();
    SampleServiceAsync async2 = SampleServiceAsync.of(sticky2, runtime);
    async2.voidToVoid();
    async2.getMyAlias();
    async2.getOptionalBinary();
    assertThat(requests).describedAs("Second batch of requests should all go to another randomly chosen host").allSatisfy(string -> assertThat(string).startsWith("[two]"));
}
Also used : SampleServiceAsync(com.palantir.dialogue.example.SampleServiceAsync) Channel(com.palantir.dialogue.Channel) SampleServiceBlocking(com.palantir.dialogue.example.SampleServiceBlocking) Test(org.junit.jupiter.api.Test)

Aggregations

SampleServiceAsync (com.palantir.dialogue.example.SampleServiceAsync)4 Test (org.junit.jupiter.api.Test)3 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)1 ServicesConfigBlock (com.palantir.conjure.java.api.config.service.ServicesConfigBlock)1 Channel (com.palantir.dialogue.Channel)1 DialogueClients (com.palantir.dialogue.clients.DialogueClients)1 ReloadingFactory (com.palantir.dialogue.clients.DialogueClients.ReloadingFactory)1 SampleServiceBlocking (com.palantir.dialogue.example.SampleServiceBlocking)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1