use of com.linkedin.r2.message.RequestContext in project rest.li by linkedin.
the class DegraderLoadBalancerTest method runMultiThreadedTest.
private void runMultiThreadedTest(final DegraderLoadBalancerStrategyAdapter strategyAdapter, final List<TrackerClient> clients, final int numberOfThread, final boolean trackerClientMustNotBeNull) {
final CountDownLatch exitLatch = new CountDownLatch(numberOfThread);
final CountDownLatch startLatch = new CountDownLatch(numberOfThread);
ExecutorService executorService = Executors.newFixedThreadPool(numberOfThread);
List<Future<Boolean>> futures = new ArrayList<Future<Boolean>>();
for (int i = 0; i < numberOfThread; i++) {
// testNG won't be able to "know" if a child thread's assertion is false, so to get around it we
// need to throw an exception so executorService can notify the main thread about the false assertion
// even though executorService has an invokeAll method, it doesn't seem run the threads at the same time
// so we have to use a latch to make sure all the threads run at the same time to simulate concurrent access
Future<Boolean> future = executorService.submit(new Runnable() {
@Override
public void run() {
startLatch.countDown();
try {
//wait until all threads are ready to run together
startLatch.await();
} catch (InterruptedException e) {
throw new RuntimeException("Failed the test because thread was interrupted");
}
// if config is broken, every thread would fail and state update would be unsuccessful
try {
TrackerClient resultTC = getTrackerClient(strategyAdapter, null, new RequestContext(), 1, clients);
if (trackerClientMustNotBeNull && resultTC == null) {
throw new RuntimeException("Failed the test because resultTC returns null");
}
} catch (DummyException ex) {
// expected
}
exitLatch.countDown();
try {
//make sure all threads are not stuck on WAIT_THREAD
if (!exitLatch.await(5, TimeUnit.SECONDS)) {
throw new RuntimeException("Failed the test because we waited longer than 1 second");
}
} catch (InterruptedException e) {
throw new RuntimeException("Failed the test because thread was interrupted");
}
}
}, Boolean.TRUE);
futures.add(future);
}
for (Future<Boolean> future : futures) {
try {
assertTrue(future.get());
} catch (Exception e) {
fail("something is failing", e);
}
}
executorService.shutdownNow();
}
use of com.linkedin.r2.message.RequestContext in project rest.li by linkedin.
the class DegraderLoadBalancerTest method testOneTrackerClient.
@Test(groups = { "small", "back-end" })
public void testOneTrackerClient() throws URISyntaxException {
DegraderLoadBalancerStrategyV3 strategy = getStrategy();
List<TrackerClient> clients = new ArrayList<TrackerClient>();
URI uri1 = URI.create("http://test.linkedin.com:3242/fdsaf");
clients.add(getClient(uri1, new TestClock()));
// should always get the only client in the list
for (int i = 0; i < 1000; ++i) {
assertEquals(getTrackerClient(strategy, null, new RequestContext(), 0, clients), clients.get(0));
}
}
use of com.linkedin.r2.message.RequestContext in project rest.li by linkedin.
the class DegraderLoadBalancerTest method testRandom.
@Test(groups = { "small", "back-end" })
public void testRandom() throws URISyntaxException {
DegraderLoadBalancerStrategyV3 strategy = getStrategy();
List<TrackerClient> clients = new ArrayList<TrackerClient>();
URI uri1 = URI.create("http://test.linkedin.com:3242/fdsaf");
URI uri2 = URI.create("http://test.linkedin.com:3243/fdsaf");
clients.add(getClient(uri1, new TestClock()));
clients.add(getClient(uri2, new TestClock()));
// since cluster call count is 0, we will default to random
for (int i = 0; i < 1000; ++i) {
TrackerClient client = getTrackerClient(strategy, null, new RequestContext(), 0, clients);
assertNotNull(client);
assertTrue(clients.contains(client));
}
}
use of com.linkedin.r2.message.RequestContext in project rest.li by linkedin.
the class DegraderLoadBalancerTest method testTargetHostHeaderBinding.
@Test
public void testTargetHostHeaderBinding() {
final int NUM_SERVERS = 10;
DegraderLoadBalancerStrategyV3 strategy = getStrategy();
List<TrackerClient> clients = new ArrayList<TrackerClient>(NUM_SERVERS);
for (int ii = 0; ii < NUM_SERVERS; ++ii) {
clients.add(getClient(URI.create("http://server" + ii + ".testing:9876/foobar")));
}
Map<TrackerClient, Integer> serverCounts = new HashMap<TrackerClient, Integer>();
RestRequestBuilder builder = new RestRequestBuilder(URI.create("d2://fooservice"));
final int NUM_REQUESTS = 100;
for (int ii = 0; ii < NUM_REQUESTS; ++ii) {
TrackerClient client = getTrackerClient(strategy, builder.build(), new RequestContext(), 0, clients);
Integer count = serverCounts.get(client);
if (count == null) {
count = 0;
}
serverCounts.put(client, count + 1);
}
//First, check that requests are normally evenly distributed.
Assert.assertEquals(serverCounts.size(), NUM_SERVERS);
serverCounts.clear();
RestRequest request = builder.build();
RequestContext context = new RequestContext();
KeyMapper.TargetHostHints.setRequestContextTargetHost(context, clients.get(0).getUri());
for (int ii = 0; ii < NUM_REQUESTS; ++ii) {
TrackerClient client = getTrackerClient(strategy, request, context, 0, clients);
Integer count = serverCounts.get(client);
if (count == null) {
count = 0;
}
serverCounts.put(client, count + 1);
}
Assert.assertEquals(serverCounts.size(), 1);
Assert.assertEquals(serverCounts.keySet().iterator().next(), clients.get(0));
}
use of com.linkedin.r2.message.RequestContext in project rest.li by linkedin.
the class DegraderLoadBalancerTest method testRegexHashingConsistency.
@Test(groups = { "small", "back-end" })
public void testRegexHashingConsistency() {
final int NUM_SERVERS = 100;
DegraderLoadBalancerStrategyV3 strategy = new DegraderLoadBalancerStrategyV3(new DegraderLoadBalancerStrategyConfig(5000, true, 100, DegraderLoadBalancerStrategyV3.HASH_METHOD_URI_REGEX, Collections.<String, Object>singletonMap(URIRegexHash.KEY_REGEXES, Collections.singletonList("(.*)")), SystemClock.instance(), DegraderLoadBalancerStrategyConfig.DEFAULT_INITIAL_RECOVERY_LEVEL, DegraderLoadBalancerStrategyConfig.DEFAULT_RAMP_FACTOR, DegraderLoadBalancerStrategyConfig.DEFAULT_HIGH_WATER_MARK, DegraderLoadBalancerStrategyConfig.DEFAULT_LOW_WATER_MARK, DegraderLoadBalancerStrategyConfig.DEFAULT_GLOBAL_STEP_UP, DegraderLoadBalancerStrategyConfig.DEFAULT_GLOBAL_STEP_DOWN, DegraderLoadBalancerStrategyConfig.DEFAULT_CLUSTER_MIN_CALL_COUNT_HIGH_WATER_MARK, DegraderLoadBalancerStrategyConfig.DEFAULT_CLUSTER_MIN_CALL_COUNT_LOW_WATER_MARK, DegraderLoadBalancerStrategyConfig.DEFAULT_HASHRING_POINT_CLEANUP_RATE, null, DegraderLoadBalancerStrategyConfig.DEFAULT_NUM_PROBES, null, DegraderLoadBalancerStrategyConfig.DEFAULT_QUARANTINE_MAXPERCENT, null, null, DegraderLoadBalancerStrategyConfig.DEFAULT_QUARANTINE_METHOD, null, DegraderLoadBalancerStrategyConfig.DEFAULT_QUARANTINE_LATENCY), "DegraderLoadBalancerTest", null);
List<TrackerClient> clients = new ArrayList<TrackerClient>(NUM_SERVERS);
for (int i = 0; i < NUM_SERVERS; i++) {
clients.add(getClient(URI.create("http://server" + i + ".testing:9876/foobar")));
}
final int NUM_URIS = 1000;
final int NUM_CHECKS = 10;
final Map<TrackerClient, Integer> serverCounts = new HashMap<TrackerClient, Integer>();
for (int i = 0; i < NUM_URIS; i++) {
URIRequest request = new URIRequest("d2://fooService/this/is/a/test/" + i);
TrackerClient lastClient = null;
for (int j = 0; j < NUM_CHECKS; j++) {
TrackerClient client = getTrackerClient(strategy, request, new RequestContext(), 0, clients);
assertNotNull(client);
if (lastClient != null) {
assertEquals(client, lastClient);
}
lastClient = client;
}
Integer count = serverCounts.get(lastClient);
if (count == null) {
count = 0;
}
serverCounts.put(lastClient, count + 1);
}
// TODO... should check the distribution of hits/server, should be pretty even, but how
// even is even? Also note this depends on pointsPerServer and other configurable parameters.
// TODO... another test will check that when a TrackerClient is removed, the distribution
// doesn't change too much.
}
Aggregations