use of com.linkedin.d2.balancer.clients.TrackerClient in project rest.li by linkedin.
the class DegraderLoadBalancerTest method testStateIsNullAndCallCountIsGreaterThanZeroWithLatency.
@Test(groups = { "small", "back-end" })
public void testStateIsNullAndCallCountIsGreaterThanZeroWithLatency() throws URISyntaxException, InterruptedException {
// check for average cluster latency < max latency
// max so we don't time out from lag on testing machine
DegraderLoadBalancerStrategyV3 strategy = new DegraderLoadBalancerStrategyV3(new DegraderLoadBalancerStrategyConfig(5000), "DegraderLoadBalancerTest", null);
List<TrackerClient> clients = new ArrayList<TrackerClient>();
TestClock clock1 = new TestClock();
TestClock clock2 = new TestClock();
clients.add(getClient(URI.create("http://test.linkedin.com:3242/fdsaf"), clock1));
clients.add(getClient(URI.create("http://test.linkedin.com:3243/fdsaf"), clock2));
for (int i = 0; i < 1000; ++i) {
clients.get(i % 2).getCallTracker().startCall().endCall();
}
clock1.addMs(5000);
// this should trigger setting _state (state is null and count > 0)
getTrackerClient(strategy, null, new RequestContext(), -1, clients);
// we chose to initialize the state first.
for (TrackerClient client : clients) {
assertEquals(client.getDegraderControl(DEFAULT_PARTITION_ID).getOverrideDropRate(), 0.0);
}
}
use of com.linkedin.d2.balancer.clients.TrackerClient in project rest.li by linkedin.
the class DegraderLoadBalancerTest method testWeightedAndLatencyDegradationBalancingRing.
@Test(groups = { "small", "back-end" }, dataProvider = "consistentHashAlgorithms")
public void testWeightedAndLatencyDegradationBalancingRing(String consistentHashAlgorithm) throws URISyntaxException {
DegraderLoadBalancerStrategyV3 strategy = getStrategy(consistentHashAlgorithm);
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");
TestClock clock1 = new TestClock();
TestClock clock2 = new TestClock();
TrackerClient client1 = new TrackerClient(uri1, getDefaultPartitionData(1d), new TestLoadBalancerClient(uri1), clock1, null);
TrackerClient client2 = new TrackerClient(uri2, getDefaultPartitionData(0.8d), new TestLoadBalancerClient(uri2), clock2, null);
clients.add(client1);
clients.add(client2);
DegraderControl dcClient2Default = client2.getDegraderControl(DEFAULT_PARTITION_ID);
dcClient2Default.setOverrideMinCallCount(1);
dcClient2Default.setMinCallCount(1);
dcClient2Default.setMaxDropRate(1d);
dcClient2Default.setUpStep(0.4d);
dcClient2Default.setHighErrorRate(0);
CallCompletion cc = client2.getCallTracker().startCall();
clock2.addMs(1);
cc.endCallWithError();
clock1.addMs(15000);
clock2.addMs(5000);
// trigger a state update
assertNotNull(getTrackerClient(strategy, null, new RequestContext(), 1, clients));
// now do a basic verification to verify getTrackerClient is properly weighting things
double calls = 10000d;
int client1Count = 0;
int client2Count = 0;
double tolerance = 0.05d;
for (int i = 0; i < calls; ++i) {
TrackerClient client = getTrackerClient(strategy, null, new RequestContext(), 1, clients);
assertNotNull(client);
if (client.getUri().equals(uri1)) {
++client1Count;
} else {
++client2Count;
}
}
assertTrue(Math.abs((client1Count / calls) - (100 / 148d)) < tolerance);
assertTrue(Math.abs((client2Count / calls) - (48 / 148d)) < tolerance);
}
use of com.linkedin.d2.balancer.clients.TrackerClient in project rest.li by linkedin.
the class DegraderLoadBalancerTest method testHighTrafficHighLatency1Client.
@Test(groups = { "small", "back-end" })
public void testHighTrafficHighLatency1Client() {
Map<String, Object> myMap = new HashMap<String, Object>();
Long timeInterval = 5000L;
TestClock clock = new TestClock();
myMap.put(PropertyKeys.CLOCK, clock);
myMap.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_INTERVAL_MS, timeInterval);
Map<String, String> degraderProperties = new HashMap<String, String>();
degraderProperties.put(PropertyKeys.DEGRADER_HIGH_ERROR_RATE, "0.5");
degraderProperties.put(PropertyKeys.DEGRADER_LOW_ERROR_RATE, "0.2");
DegraderImpl.Config degraderConfig = DegraderConfigFactory.toDegraderConfig(degraderProperties);
double qps = 121;
//test Strategy V3
List<TrackerClient> clients = createTrackerClient(1, clock, degraderConfig);
DegraderLoadBalancerStrategyConfig config = DegraderLoadBalancerStrategyConfig.createHttpConfigFromMap(myMap);
DegraderLoadBalancerStrategyV3 strategyV3 = new DegraderLoadBalancerStrategyV3(config, "DegraderLoadBalancerTest", null);
DegraderLoadBalancerStrategyAdapter strategy = new DegraderLoadBalancerStrategyAdapter(strategyV3);
testDegraderLoadBalancerSimulator(strategy, clock, timeInterval, clients, qps, degraderConfig);
//test Strategy V2
clients = createTrackerClient(1, clock, degraderConfig);
config = DegraderLoadBalancerStrategyConfig.createHttpConfigFromMap(myMap);
DegraderLoadBalancerStrategyV2_1 strategyV2 = new DegraderLoadBalancerStrategyV2_1(config, "DegraderLoadBalancerTest", null);
strategy = new DegraderLoadBalancerStrategyAdapter(strategyV2);
testDegraderLoadBalancerSimulator(strategy, clock, timeInterval, clients, qps, degraderConfig);
}
use of com.linkedin.d2.balancer.clients.TrackerClient 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.d2.balancer.clients.TrackerClient in project rest.li by linkedin.
the class DegraderLoadBalancerTest method stressTest.
@Test(groups = { "small", "back-end" })
public void stressTest() {
final DegraderLoadBalancerStrategyV3 strategyV3 = getStrategy();
TestClock testClock = new TestClock();
String baseUri = "http://linkedin.com:9999";
int numberOfPartitions = 10;
Map<String, String> degraderProperties = new HashMap<String, String>();
degraderProperties.put(PropertyKeys.DEGRADER_HIGH_ERROR_RATE, "0.5");
degraderProperties.put(PropertyKeys.DEGRADER_LOW_ERROR_RATE, "0.2");
DegraderImpl.Config degraderConfig = DegraderConfigFactory.toDegraderConfig(degraderProperties);
final List<TrackerClient> clients = new ArrayList<TrackerClient>();
for (int i = 0; i < numberOfPartitions; i++) {
URI uri = URI.create(baseUri + i);
TrackerClient client = new TrackerClient(uri, getDefaultPartitionData(1, numberOfPartitions), new TestLoadBalancerClient(uri), testClock, degraderConfig);
clients.add(client);
}
final ExecutorService executor = Executors.newFixedThreadPool(100);
final CountDownLatch startLatch = new CountDownLatch(1);
final CountDownLatch finishLatch = new CountDownLatch(100);
try {
for (int i = 0; i < numberOfPartitions; i++) {
Assert.assertFalse(strategyV3.getState().getPartitionState(i).isInitialized());
}
for (int i = 0; i < 100; i++) {
final int partitionId = i % numberOfPartitions;
executor.submit(new Runnable() {
@Override
public void run() {
try {
startLatch.await();
} catch (InterruptedException ex) {
}
strategyV3.getRing(1, partitionId, clients);
finishLatch.countDown();
}
});
}
// all threads would try to getRing simultanously
startLatch.countDown();
if (!finishLatch.await(10, TimeUnit.SECONDS)) {
fail("Stress test failed to finish within 10 seconds");
}
for (int i = 0; i < numberOfPartitions; i++) {
Assert.assertTrue(strategyV3.getState().getPartitionState(i).isInitialized());
}
} catch (InterruptedException ex) {
} finally {
executor.shutdownNow();
}
}
Aggregations