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");
}
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]"));
}
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]"));
}
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]"));
}
Aggregations