use of com.linkedin.d2.balancer.clients.DegraderTrackerClient in project rest.li by linkedin.
the class DegraderLoadBalancerTest method callClients.
/**
* simulates calling clients
* @param milliseconds latency of the call
* @param qps qps of traffic per client
* @param clients list of clients being called
* @param clock
* @param timeInterval
* @param withError calling client with error that we don't use for load balancing (any generic error)
* @param withQualifiedDegraderError calling client with error that we use for load balancing
*/
private void callClients(long milliseconds, double qps, List<DegraderTrackerClient> clients, TestClock clock, long timeInterval, boolean withError, boolean withQualifiedDegraderError) {
LinkedList<CallCompletion> callCompletions = new LinkedList<>();
int callHowManyTimes = (int) ((qps * timeInterval) / 1000);
for (int i = 0; i < callHowManyTimes; i++) {
for (DegraderTrackerClient client : clients) {
CallCompletion cc = client.getCallTracker().startCall();
callCompletions.add(cc);
}
}
Random random = new Random();
clock.addMs(milliseconds);
for (CallCompletion cc : callCompletions) {
if (withError) {
cc.endCallWithError();
} else if (withQualifiedDegraderError) {
// choose a random error type
if (random.nextBoolean()) {
cc.endCallWithError(ErrorType.CLOSED_CHANNEL_EXCEPTION);
} else {
cc.endCallWithError(ErrorType.CONNECT_EXCEPTION);
}
} else {
cc.endCall();
}
}
// complete a full interval cycle
clock.addMs(timeInterval - (milliseconds % timeInterval));
}
use of com.linkedin.d2.balancer.clients.DegraderTrackerClient in project rest.li by linkedin.
the class DegraderTrackerClientTest method testClientStreamRequest.
@Test(groups = { "small", "back-end" })
public void testClientStreamRequest() throws URISyntaxException {
URI uri = URI.create("http://test.qa.com:1234/foo");
double weight = 3d;
TestClient wrappedClient = new TestClient(true);
Clock clock = new SettableClock();
Map<Integer, PartitionData> partitionDataMap = createDefaultPartitionData(3d);
DegraderTrackerClient client = new DegraderTrackerClientImpl(uri, partitionDataMap, wrappedClient, clock, null);
Assert.assertEquals(client.getUri(), uri);
Double clientWeight = client.getPartitionWeight(DefaultPartitionAccessor.DEFAULT_PARTITION_ID);
Assert.assertEquals(clientWeight, weight);
Assert.assertEquals(client.getTransportClient(), wrappedClient);
StreamRequest streamRequest = new StreamRequestBuilder(uri).build(EntityStreams.emptyStream());
Map<String, String> restWireAttrs = new HashMap<>();
TestTransportCallback<StreamResponse> restCallback = new TestTransportCallback<>();
client.streamRequest(streamRequest, new RequestContext(), restWireAttrs, restCallback);
Assert.assertFalse(restCallback.response.hasError());
Assert.assertSame(wrappedClient.streamRequest, streamRequest);
Assert.assertEquals(wrappedClient.restWireAttrs, restWireAttrs);
}
use of com.linkedin.d2.balancer.clients.DegraderTrackerClient in project rest.li by linkedin.
the class DegraderTrackerClientTest method testDoNotSlowStartWhenTrue.
@Test
public void testDoNotSlowStartWhenTrue() {
Map<Integer, PartitionData> partitionDataMap = createDefaultPartitionData(1d);
DegraderImpl.Config config = new DegraderImpl.Config();
double initialDropRate = 0.99d;
config.setInitialDropRate(initialDropRate);
DegraderTrackerClient client = new DegraderTrackerClientImpl(URI.create("http://test.qa.com:1234/foo"), partitionDataMap, new TestClient(), new SettableClock(), config, DegraderLoadBalancerStrategyConfig.DEFAULT_UPDATE_INTERVAL_MS, TrackerClientImpl.DEFAULT_ERROR_STATUS_PATTERN, true);
DegraderControl degraderControl = client.getDegraderControl(DefaultPartitionAccessor.DEFAULT_PARTITION_ID);
Assert.assertEquals(degraderControl.getInitialDropRate(), DegraderImpl.DEFAULT_DO_NOT_SLOW_START_INITIAL_DROP_RATE, "Initial drop rate in config should have been overridden by doNotSlowStart uri property.");
}
use of com.linkedin.d2.balancer.clients.DegraderTrackerClient in project rest.li by linkedin.
the class DegraderLoadBalancerTest method testshouldUpdatePartition.
@Test(groups = { "small", "back-end" })
public void testshouldUpdatePartition() throws URISyntaxException {
Map<String, Object> myConfig = new HashMap<>();
TestClock testClock = new TestClock();
myConfig.put(PropertyKeys.CLOCK, testClock);
myConfig.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_INTERVAL_MS, 5000L);
myConfig.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_MAX_CLUSTER_LATENCY_WITHOUT_DEGRADING, 100d);
DegraderLoadBalancerStrategyV3 strategy = getStrategy(myConfig);
List<DegraderTrackerClient> clients = new ArrayList<>();
Map<URI, Integer> pointsMap = new HashMap<>();
long clusterCallCount = 15;
RingFactory<URI> ringFactory = new DelegatingRingFactory<>(new DegraderLoadBalancerStrategyConfig(1L));
URI uri1 = URI.create("http://test.linkedin.com:3242/fdsaf");
URI uri2 = URI.create("http://test.linkedin.com:3243/fdsaf");
clients.add(getClient(uri1));
clients.add(getClient(uri2));
pointsMap.put(uri1, 1);
pointsMap.put(uri2, 1);
// state is default initialized, new cluster generation
assertTrue(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(0, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
PartitionDegraderLoadBalancerState current = strategy.getState().getPartitionState(DEFAULT_PARTITION_ID);
current = new PartitionDegraderLoadBalancerState(0, testClock._currentTimeMillis, true, ringFactory, pointsMap, PartitionDegraderLoadBalancerState.Strategy.LOAD_BALANCE, 0.0, -1, new HashMap<>(), "Test", current.getDegraderProperties(), clusterCallCount, 0, 0, Collections.emptyMap(), Collections.emptyMap(), null, 0);
strategy.getState().setPartitionState(DEFAULT_PARTITION_ID, current);
// state is not null, but we're on the same cluster generation id, and 5 seconds
// haven't gone by
testClock.addMs(1);
assertFalse(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(0, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
// generation Id for the next state is changed
current = new PartitionDegraderLoadBalancerState(1, testClock._currentTimeMillis, true, ringFactory, pointsMap, PartitionDegraderLoadBalancerState.Strategy.LOAD_BALANCE, 0.0, -1, new HashMap<>(), "Test", current.getDegraderProperties(), clusterCallCount, 0, 0, Collections.emptyMap(), Collections.emptyMap(), null, 0);
strategy.getState().setPartitionState(DEFAULT_PARTITION_ID, current);
// state is not null, and cluster generation has changed so we will update
testClock.addMs(1);
assertTrue(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(0, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
// state is not null, and force 5s to go by with the same cluster generation id
current = new PartitionDegraderLoadBalancerState(1, testClock._currentTimeMillis, true, ringFactory, pointsMap, PartitionDegraderLoadBalancerState.Strategy.LOAD_BALANCE, 0.0, -1, new HashMap<>(), "Test", current.getDegraderProperties(), clusterCallCount, 0, 0, Collections.emptyMap(), Collections.emptyMap(), null, 0);
strategy.getState().setPartitionState(DEFAULT_PARTITION_ID, current);
testClock.addMs(5000);
assertTrue(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(1, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
current = new PartitionDegraderLoadBalancerState(1, testClock._currentTimeMillis, true, ringFactory, pointsMap, PartitionDegraderLoadBalancerState.Strategy.LOAD_BALANCE, 0.0, -1, new HashMap<>(), "Test", current.getDegraderProperties(), clusterCallCount, 0, 0, Collections.emptyMap(), Collections.emptyMap(), null, 0);
strategy.getState().setPartitionState(DEFAULT_PARTITION_ID, current);
// now try a new cluster generation id so state will be updated again
testClock.addMs(15);
assertTrue(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(2, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
}
use of com.linkedin.d2.balancer.clients.DegraderTrackerClient in project rest.li by linkedin.
the class DegraderLoadBalancerTest method testshouldUpdatePartitionOnlyAtInterval.
@Test(groups = { "small", "back-end" })
public void testshouldUpdatePartitionOnlyAtInterval() throws URISyntaxException {
Map<String, Object> myConfig = new HashMap<>();
TestClock testClock = new TestClock();
myConfig.put(PropertyKeys.CLOCK, testClock);
myConfig.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_INTERVAL_MS, 5000L);
myConfig.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_MAX_CLUSTER_LATENCY_WITHOUT_DEGRADING, 100d);
myConfig.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_ONLY_AT_INTERVAL, true);
DegraderLoadBalancerStrategyV3 strategy = getStrategy(myConfig);
List<DegraderTrackerClient> clients = new ArrayList<>();
Map<URI, Integer> pointsMap = new HashMap<>();
long clusterCallCount = 15;
RingFactory<URI> ringFactory = new DelegatingRingFactory<>(new DegraderLoadBalancerStrategyConfig(1L));
URI uri1 = URI.create("http://test.linkedin.com:3242/fdsaf");
URI uri2 = URI.create("http://test.linkedin.com:3243/fdsaf");
clients.add(getClient(uri1));
clients.add(getClient(uri2));
pointsMap.put(uri1, 1);
pointsMap.put(uri2, 1);
PartitionDegraderLoadBalancerState current = strategy.getState().getPartitionState(DEFAULT_PARTITION_ID);
current = new PartitionDegraderLoadBalancerState(0, testClock._currentTimeMillis, true, ringFactory, pointsMap, PartitionDegraderLoadBalancerState.Strategy.LOAD_BALANCE, 0.0, -1, new HashMap<>(), "Test", current.getDegraderProperties(), clusterCallCount, 0, 0, Collections.emptyMap(), Collections.emptyMap(), null, 0);
strategy.getState().setPartitionState(DEFAULT_PARTITION_ID, current);
// state is default initialized, new cluster generation
assertFalse(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(0, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
// state is not null, but we're on the same cluster generation id, and 5 seconds
// haven't gone by
testClock.addMs(1);
assertFalse(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(0, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
testClock.addMs(5000);
assertTrue(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(1, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
current = new PartitionDegraderLoadBalancerState(1, testClock._currentTimeMillis, true, new DelegatingRingFactory<>(new DegraderLoadBalancerStrategyConfig(1L)), pointsMap, PartitionDegraderLoadBalancerState.Strategy.LOAD_BALANCE, 0.0, -1, new HashMap<>(), "Test", current.getDegraderProperties(), clusterCallCount, 0, 0, Collections.emptyMap(), Collections.emptyMap(), null, 0);
strategy.getState().setPartitionState(DEFAULT_PARTITION_ID, current);
}
Aggregations