Search in sources :

Example 46 with DegraderTrackerClient

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));
}
Also used : CallCompletion(com.linkedin.util.degrader.CallCompletion) Random(java.util.Random) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) LinkedList(java.util.LinkedList)

Example 47 with DegraderTrackerClient

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);
}
Also used : HashMap(java.util.HashMap) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) ByteString(com.linkedin.data.ByteString) Clock(com.linkedin.util.clock.Clock) SettableClock(com.linkedin.util.clock.SettableClock) URI(java.net.URI) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PartitionData(com.linkedin.d2.balancer.properties.PartitionData) SettableClock(com.linkedin.util.clock.SettableClock) RequestContext(com.linkedin.r2.message.RequestContext) Test(org.testng.annotations.Test)

Example 48 with DegraderTrackerClient

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.");
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PartitionData(com.linkedin.d2.balancer.properties.PartitionData) DegraderLoadBalancerStrategyConfig(com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyConfig) DegraderImpl(com.linkedin.util.degrader.DegraderImpl) DegraderControl(com.linkedin.util.degrader.DegraderControl) SettableClock(com.linkedin.util.clock.SettableClock) Test(org.testng.annotations.Test)

Example 49 with DegraderTrackerClient

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));
}
Also used : HashMap(java.util.HashMap) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) ArrayList(java.util.ArrayList) URI(java.net.URI) DelegatingRingFactory(com.linkedin.d2.balancer.strategies.DelegatingRingFactory) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Example 50 with DegraderTrackerClient

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);
}
Also used : HashMap(java.util.HashMap) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) ArrayList(java.util.ArrayList) URI(java.net.URI) DelegatingRingFactory(com.linkedin.d2.balancer.strategies.DelegatingRingFactory) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Aggregations

DegraderTrackerClient (com.linkedin.d2.balancer.clients.DegraderTrackerClient)58 Test (org.testng.annotations.Test)46 DegraderTrackerClientTest (com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)42 ArrayList (java.util.ArrayList)34 URI (java.net.URI)31 RequestContext (com.linkedin.r2.message.RequestContext)30 TrackerClient (com.linkedin.d2.balancer.clients.TrackerClient)20 DegraderImpl (com.linkedin.util.degrader.DegraderImpl)19 AtomicLong (java.util.concurrent.atomic.AtomicLong)17 DegraderControl (com.linkedin.util.degrader.DegraderControl)16 HashMap (java.util.HashMap)16 DegraderTrackerClientImpl (com.linkedin.d2.balancer.clients.DegraderTrackerClientImpl)14 CallCompletion (com.linkedin.util.degrader.CallCompletion)11 URIRequest (com.linkedin.d2.balancer.util.URIRequest)9 PartitionData (com.linkedin.d2.balancer.properties.PartitionData)7 SettableClock (com.linkedin.util.clock.SettableClock)6 LoadBalancerQuarantine (com.linkedin.d2.balancer.strategies.LoadBalancerQuarantine)4 RestRequest (com.linkedin.r2.message.rest.RestRequest)4 CountDownLatch (java.util.concurrent.CountDownLatch)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4