Search in sources :

Example 1 with ConsistentHashAlgorithm

use of com.linkedin.d2.ConsistentHashAlgorithm in project rest.li by linkedin.

the class LoadBalancerStrategyPropertiesConverter method toConfig.

@SuppressWarnings({ "unchecked" })
public static D2LoadBalancerStrategyProperties toConfig(Map<String, Object> properties) {
    D2LoadBalancerStrategyProperties config = new D2LoadBalancerStrategyProperties();
    if (properties.containsKey(PropertyKeys.HTTP_LB_GLOBAL_STEP_DOWN)) {
        config.setGlobalStepDown(coerce(properties.get(PropertyKeys.HTTP_LB_GLOBAL_STEP_DOWN), Double.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_GLOBAL_STEP_UP)) {
        config.setGlobalStepUp(coerce(properties.get(PropertyKeys.HTTP_LB_GLOBAL_STEP_UP), Double.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_INITIAL_RECOVERY_LEVEL)) {
        config.setInitialRecoveryLevel(coerce(properties.get(PropertyKeys.HTTP_LB_INITIAL_RECOVERY_LEVEL), Double.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_RING_RAMP_FACTOR)) {
        config.setRingRampFactor(coerce(properties.get(PropertyKeys.HTTP_LB_RING_RAMP_FACTOR), Double.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_HIGH_WATER_MARK)) {
        config.setHighWaterMark(coerce(properties.get(PropertyKeys.HTTP_LB_HIGH_WATER_MARK), Double.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_LOW_WATER_MARK)) {
        config.setLowWaterMark(coerce(properties.get(PropertyKeys.HTTP_LB_LOW_WATER_MARK), Double.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_POINTS_PER_WEIGHT)) {
        config.setPointsPerWeight(coerce(properties.get(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_POINTS_PER_WEIGHT), Integer.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_INTERVAL_MS)) {
        config.setUpdateIntervalMs(coerce(properties.get(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_INTERVAL_MS), Long.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_CLUSTER_MIN_CALL_COUNT_HIGH_WATER_MARK)) {
        config.setMinCallCountHighWaterMark(coerce(properties.get(PropertyKeys.HTTP_LB_CLUSTER_MIN_CALL_COUNT_HIGH_WATER_MARK), Long.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_CLUSTER_MIN_CALL_COUNT_LOW_WATER_MARK)) {
        config.setMinCallCountLowWaterMark(coerce(properties.get(PropertyKeys.HTTP_LB_CLUSTER_MIN_CALL_COUNT_LOW_WATER_MARK), Long.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_HASHRING_POINT_CLEANUP_RATE)) {
        config.setHashRingPointCleanupRate(coerce(properties.get(PropertyKeys.HTTP_LB_HASHRING_POINT_CLEANUP_RATE), Double.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_HASH_METHOD)) {
        String hashMethodString = coerce(properties.get(PropertyKeys.HTTP_LB_HASH_METHOD), String.class);
        if (DegraderLoadBalancerStrategyV3.HASH_METHOD_NONE.equalsIgnoreCase(hashMethodString)) {
            config.setHashMethod(hashMethodEnum.RANDOM);
        } else if (DegraderLoadBalancerStrategyV3.HASH_METHOD_URI_REGEX.equalsIgnoreCase(hashMethodString)) {
            config.setHashMethod(hashMethodEnum.URI_REGEX);
        }
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_HASH_CONFIG)) {
        hashConfigType hashConfig = new hashConfigType();
        Map<String, Object> hashConfigProperties = (Map<String, Object>) properties.get(PropertyKeys.HTTP_LB_HASH_CONFIG);
        if (hashConfigProperties.containsKey(URIRegexHash.KEY_REGEXES)) {
            List<String> uriRegexes = (List<String>) hashConfigProperties.get(URIRegexHash.KEY_REGEXES);
            hashConfig.setUriRegexes(new StringArray(uriRegexes));
        }
        if (hashConfigProperties.containsKey(URIRegexHash.KEY_WARN_ON_NO_MATCH)) {
            String warnOnNoMatchString = (String) hashConfigProperties.get(URIRegexHash.KEY_WARN_ON_NO_MATCH);
            hashConfig.setWarnOnNoMatch(Boolean.parseBoolean(warnOnNoMatchString));
        }
        if (hashConfigProperties.containsKey(URIRegexHash.KEY_FAIL_ON_NO_MATCH)) {
            String failOnNoMatchString = (String) hashConfigProperties.get(URIRegexHash.KEY_FAIL_ON_NO_MATCH);
            hashConfig.setFailOnNoMatch(Boolean.parseBoolean(failOnNoMatchString));
        }
        config.setHashConfig(hashConfig);
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_ONLY_AT_INTERVAL)) {
        config.setUpdateOnlyAtInterval(coerce(properties.get(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_ONLY_AT_INTERVAL), Boolean.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_CONSISTENT_HASH_ALGORITHM)) {
        String consistentHashAlgorithm = coerce(properties.get(PropertyKeys.HTTP_LB_CONSISTENT_HASH_ALGORITHM), String.class);
        if (DelegatingRingFactory.POINT_BASED_CONSISTENT_HASH.equalsIgnoreCase(consistentHashAlgorithm)) {
            config.setConsistentHashAlgorithm(ConsistentHashAlgorithmEnum.POINT_BASED);
        } else if (DelegatingRingFactory.MULTI_PROBE_CONSISTENT_HASH.equalsIgnoreCase(consistentHashAlgorithm)) {
            config.setConsistentHashAlgorithm(ConsistentHashAlgorithmEnum.MULTI_PROBE);
        } else if (DelegatingRingFactory.DISTRIBUTION_NON_HASH.equalsIgnoreCase(consistentHashAlgorithm)) {
            config.setConsistentHashAlgorithm(ConsistentHashAlgorithmEnum.DISTRIBUTION_BASED);
        }
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_CONSISTENT_HASH_NUM_PROBES)) {
        config.setNumberOfProbes(coerce(properties.get(PropertyKeys.HTTP_LB_CONSISTENT_HASH_NUM_PROBES), Integer.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_CONSISTENT_HASH_POINTS_PER_HOST)) {
        config.setNumberOfPointsPerHost(coerce(properties.get(PropertyKeys.HTTP_LB_CONSISTENT_HASH_POINTS_PER_HOST), Integer.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_CONSISTENT_HASH_BOUNDED_LOAD_BALANCING_FACTOR)) {
        config.setBoundedLoadBalancingFactor(coerce(properties.get(PropertyKeys.HTTP_LB_CONSISTENT_HASH_BOUNDED_LOAD_BALANCING_FACTOR), Double.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_QUARANTINE_MAX_PERCENT) || properties.containsKey(PropertyKeys.HTTP_LB_QUARANTINE_METHOD)) {
        quarantineInfo quarantineInfo = new quarantineInfo();
        if (properties.containsKey(PropertyKeys.HTTP_LB_QUARANTINE_MAX_PERCENT)) {
            quarantineInfo.setQuarantineMaxPercent(coerce(properties.get(PropertyKeys.HTTP_LB_QUARANTINE_MAX_PERCENT), Double.class));
        }
        if (properties.containsKey(PropertyKeys.HTTP_LB_QUARANTINE_METHOD)) {
            quarantineInfo.setQuarantineMethod(coerce(properties.get(PropertyKeys.HTTP_LB_QUARANTINE_METHOD), String.class));
        }
        config.setQuarantineCfg(quarantineInfo);
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_ERROR_STATUS_REGEX)) {
        config.setErrorStatusRegex(coerce(properties.get(PropertyKeys.HTTP_LB_ERROR_STATUS_REGEX), String.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_LOW_EVENT_EMITTING_INTERVAL)) {
        config.setLowEmittingInterval(coerce(properties.get(PropertyKeys.HTTP_LB_LOW_EVENT_EMITTING_INTERVAL), Integer.class));
    }
    if (properties.containsKey(PropertyKeys.HTTP_LB_HIGH_EVENT_EMITTING_INTERVAL)) {
        config.setHighEmittingInterval(coerce(properties.get(PropertyKeys.HTTP_LB_HIGH_EVENT_EMITTING_INTERVAL), Integer.class));
    }
    return config;
}
Also used : StringArray(com.linkedin.data.template.StringArray) com.linkedin.d2.quarantineInfo(com.linkedin.d2.quarantineInfo) D2LoadBalancerStrategyProperties(com.linkedin.d2.D2LoadBalancerStrategyProperties) List(java.util.List) com.linkedin.d2.hashConfigType(com.linkedin.d2.hashConfigType) HashMap(java.util.HashMap) Map(java.util.Map)

Example 2 with ConsistentHashAlgorithm

use of com.linkedin.d2.ConsistentHashAlgorithm in project rest.li by linkedin.

the class RelativeStrategyPropertiesConverter method toRingProperties.

@SuppressWarnings({ "unchecked" })
private static D2RingProperties toRingProperties(Map<String, Object> ringPropertyMap) {
    D2RingProperties ringProperties = new D2RingProperties();
    if (ringPropertyMap.containsKey(PropertyKeys.RING_POINTS_PER_WEIGHT)) {
        ringProperties.setPointsPerWeight(coerce(ringPropertyMap.get(PropertyKeys.RING_POINTS_PER_WEIGHT), Integer.class));
    }
    if (ringPropertyMap.containsKey(PropertyKeys.RING_HASH_METHOD)) {
        String hashMethod = (String) ringPropertyMap.get(PropertyKeys.RING_HASH_METHOD);
        if (HashMethod.URI_REGEX.name().equalsIgnoreCase(hashMethod) || RelativeLoadBalancerStrategy.HASH_METHOD_URI_REGEX.equalsIgnoreCase(hashMethod)) {
            ringProperties.setHashMethod(HashMethod.URI_REGEX);
        } else if (HashMethod.RANDOM.name().equalsIgnoreCase(hashMethod)) {
            ringProperties.setHashMethod(HashMethod.RANDOM);
        }
    }
    if (ringPropertyMap.containsKey(PropertyKeys.RING_HASH_CONFIG)) {
        HashConfig hashConfig = toHashConfig((Map<String, Object>) ringPropertyMap.get(PropertyKeys.RING_HASH_CONFIG));
        ringProperties.setHashConfig(hashConfig);
    }
    if (ringPropertyMap.containsKey(PropertyKeys.RING_HASH_RING_POINT_CLEANUP_RATE)) {
        ringProperties.setHashRingPointCleanupRate(coerce(ringPropertyMap.get(PropertyKeys.RING_HASH_RING_POINT_CLEANUP_RATE), Double.class));
    }
    if (ringPropertyMap.containsKey(PropertyKeys.RING_CONSISTENT_HASH_ALGORITHM)) {
        String consistentHashAlgorithm = (String) ringPropertyMap.get(PropertyKeys.RING_CONSISTENT_HASH_ALGORITHM);
        if (DelegatingRingFactory.POINT_BASED_CONSISTENT_HASH.equalsIgnoreCase(consistentHashAlgorithm)) {
            ringProperties.setConsistentHashAlgorithm(ConsistentHashAlgorithm.POINT_BASED);
        } else if (DelegatingRingFactory.MULTI_PROBE_CONSISTENT_HASH.equalsIgnoreCase(consistentHashAlgorithm)) {
            ringProperties.setConsistentHashAlgorithm(ConsistentHashAlgorithm.MULTI_PROBE);
        } else if (DelegatingRingFactory.DISTRIBUTION_NON_HASH.equalsIgnoreCase(consistentHashAlgorithm)) {
            ringProperties.setConsistentHashAlgorithm(ConsistentHashAlgorithm.DISTRIBUTION_BASED);
        }
    }
    if (ringPropertyMap.containsKey(PropertyKeys.RING_NUMBER_OF_PROBES)) {
        ringProperties.setNumberOfProbes(coerce(ringPropertyMap.get(PropertyKeys.RING_NUMBER_OF_PROBES), Integer.class));
    }
    if (ringPropertyMap.containsKey(PropertyKeys.RING_NUMBER_OF_POINTS_PER_HOST)) {
        ringProperties.setNumberOfPointsPerHost(coerce(ringPropertyMap.get(PropertyKeys.RING_NUMBER_OF_POINTS_PER_HOST), Integer.class));
    }
    if (ringPropertyMap.containsKey(PropertyKeys.RING_BOUNDED_LOAD_BALANCING_FACTOR)) {
        ringProperties.setBoundedLoadBalancingFactor(coerce(ringPropertyMap.get(PropertyKeys.RING_BOUNDED_LOAD_BALANCING_FACTOR), Double.class));
    }
    return ringProperties;
}
Also used : HashConfig(com.linkedin.d2.HashConfig) D2RingProperties(com.linkedin.d2.D2RingProperties)

Example 3 with ConsistentHashAlgorithm

use of com.linkedin.d2.ConsistentHashAlgorithm in project rest.li by linkedin.

the class DegraderLoadBalancerTest method testWeightedBalancingRing.

@Test(groups = { "small", "back-end" }, dataProvider = "consistentHashAlgorithms")
public void testWeightedBalancingRing(String consistentHashAlgorithm) throws URISyntaxException {
    DegraderLoadBalancerStrategyV3 strategy = getStrategy(consistentHashAlgorithm);
    List<DegraderTrackerClient> clients = new ArrayList<>();
    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();
    DegraderTrackerClient client1 = new DegraderTrackerClientImpl(uri1, getDefaultPartitionData(1d), new TestLoadBalancerClient(uri1), clock1, null);
    DegraderTrackerClient client2 = new DegraderTrackerClientImpl(uri2, getDefaultPartitionData(0.8d), new TestLoadBalancerClient(uri2), clock2, null);
    clients.add(client1);
    clients.add(client2);
    // 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 / 180d)) < tolerance);
    assertTrue(Math.abs((client2Count / calls) - (80 / 180d)) < tolerance);
}
Also used : DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) ArrayList(java.util.ArrayList) DegraderTrackerClientImpl(com.linkedin.d2.balancer.clients.DegraderTrackerClientImpl) RequestContext(com.linkedin.r2.message.RequestContext) URI(java.net.URI) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Example 4 with ConsistentHashAlgorithm

use of com.linkedin.d2.ConsistentHashAlgorithm in project rest.li by linkedin.

the class DegraderLoadBalancerTest method testWeightedAndLatencyDegradationBalancingRingWithPartitions.

@Test(groups = { "small", "back-end" }, dataProvider = "consistentHashAlgorithms")
public void testWeightedAndLatencyDegradationBalancingRingWithPartitions(String consistentHashAlgorithm) throws URISyntaxException {
    DegraderLoadBalancerStrategyV3 strategy = getStrategy(consistentHashAlgorithm);
    Map<URI, TrackerClient> clientsForPartition0 = new HashMap<>();
    Map<URI, TrackerClient> clientsForPartition1 = new HashMap<>();
    URI uri1 = URI.create("http://someTestService/someTestUrl");
    URI uri2 = URI.create("http://abcxfweuoeueoueoueoukeueoueoueoueoueouo/2354");
    URI uri3 = URI.create("http://slashdot/blah");
    URI uri4 = URI.create("http://idle/server");
    TestClock clock1 = new TestClock();
    TestClock clock2 = new TestClock();
    TestClock clock3 = new TestClock();
    @SuppressWarnings("serial") DegraderTrackerClient client1 = new DegraderTrackerClientImpl(uri1, new HashMap<Integer, PartitionData>() {

        {
            put(0, new PartitionData(1d));
        }
    }, new TestLoadBalancerClient(uri1), clock1, null);
    @SuppressWarnings("serial") DegraderTrackerClient client2 = new DegraderTrackerClientImpl(uri2, new HashMap<Integer, PartitionData>() {

        {
            put(0, new PartitionData(0.5d));
            put(1, new PartitionData(0.5d));
        }
    }, new TestLoadBalancerClient(uri2), clock2, null);
    @SuppressWarnings("serial") DegraderTrackerClient client3 = new DegraderTrackerClientImpl(uri3, new HashMap<Integer, PartitionData>() {

        {
            put(1, new PartitionData(1d));
        }
    }, new TestLoadBalancerClient(uri3), clock3, null);
    final int partitionId0 = 0;
    clientsForPartition0.put(client1.getUri(), client1);
    clientsForPartition0.put(client2.getUri(), client2);
    final int partitionId1 = 1;
    clientsForPartition1.put(client2.getUri(), client2);
    clientsForPartition1.put(client3.getUri(), client3);
    // force client2 to be disabled
    DegraderControl dcClient2Partition0 = client2.getDegraderControl(0);
    DegraderControl dcClient2Partition1 = client2.getDegraderControl(1);
    dcClient2Partition0.setOverrideMinCallCount(1);
    dcClient2Partition0.setMinCallCount(1);
    dcClient2Partition0.setMaxDropRate(1d);
    dcClient2Partition0.setUpStep(0.4d);
    dcClient2Partition0.setHighErrorRate(0);
    dcClient2Partition1.setOverrideMinCallCount(1);
    dcClient2Partition1.setMinCallCount(1);
    dcClient2Partition1.setMaxDropRate(1d);
    dcClient2Partition1.setUpStep(0.4d);
    dcClient2Partition1.setHighErrorRate(0);
    CallCompletion cc = client2.getCallTracker().startCall();
    clock2.addMs(1);
    cc.endCallWithError();
    // force client3 to be disabled
    DegraderControl dcClient3Partition1 = client3.getDegraderControl(1);
    dcClient3Partition1.setOverrideMinCallCount(1);
    dcClient3Partition1.setMinCallCount(1);
    dcClient3Partition1.setMaxDropRate(1d);
    dcClient3Partition1.setHighErrorRate(0);
    dcClient3Partition1.setUpStep(0.2d);
    CallCompletion cc3 = client3.getCallTracker().startCall();
    clock3.addMs(1);
    cc3.endCallWithError();
    clock1.addMs(15000);
    clock2.addMs(5000);
    clock3.addMs(5000);
    // trigger a state update
    assertNotNull(strategy.getTrackerClient(null, new RequestContext(), 1, partitionId0, clientsForPartition0));
    assertNotNull(strategy.getTrackerClient(null, new RequestContext(), 1, partitionId1, clientsForPartition1));
    assertNotNull(strategy.getRing(1, partitionId0, clientsForPartition0));
    assertNotNull(strategy.getRing(1, partitionId1, clientsForPartition1));
    // now do a basic verification to verify getTrackerClient is properly weighting things
    int calls = 10000;
    int client1Count = 0;
    int client2Count = 0;
    double tolerance = 0.05d;
    for (int i = 0; i < calls; ++i) {
        TrackerClient client = strategy.getTrackerClient(null, new RequestContext(), 1, partitionId0, clientsForPartition0);
        assertNotNull(client);
        if (client.getUri().equals(uri1)) {
            ++client1Count;
        } else {
            ++client2Count;
        }
    }
    assertTrue(Math.abs((client1Count / (double) calls) - (100 / 130d)) < tolerance);
    assertTrue(Math.abs((client2Count / (double) calls) - (30 / 130d)) < tolerance);
    client2Count = 0;
    int client3Count = 0;
    int client4Count = 0;
    for (int i = 0; i < calls; ++i) {
        TrackerClient client = strategy.getTrackerClient(null, new RequestContext(), 1, partitionId1, clientsForPartition1);
        assertNotNull(client);
        if (client.getUri().equals(uri3)) {
            ++client3Count;
        } else if (client.getUri().equals(uri2)) {
            ++client2Count;
        } else {
            ++client4Count;
        }
    }
    assertTrue(Math.abs((client3Count / (double) calls) - (80 / 110d)) < tolerance);
    assertTrue(Math.abs((client2Count / (double) calls) - (30 / 110d)) < tolerance);
    assertTrue(client4Count == 0);
}
Also used : HashMap(java.util.HashMap) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) DegraderControl(com.linkedin.util.degrader.DegraderControl) URI(java.net.URI) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) CallCompletion(com.linkedin.util.degrader.CallCompletion) PartitionData(com.linkedin.d2.balancer.properties.PartitionData) DegraderTrackerClientImpl(com.linkedin.d2.balancer.clients.DegraderTrackerClientImpl) RequestContext(com.linkedin.r2.message.RequestContext) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Example 5 with ConsistentHashAlgorithm

use of com.linkedin.d2.ConsistentHashAlgorithm 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<DegraderTrackerClient> clients = new ArrayList<>();
    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();
    DegraderTrackerClient client1 = new DegraderTrackerClientImpl(uri1, getDefaultPartitionData(1d), new TestLoadBalancerClient(uri1), clock1, null);
    DegraderTrackerClient client2 = new DegraderTrackerClientImpl(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);
}
Also used : DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) ArrayList(java.util.ArrayList) DegraderControl(com.linkedin.util.degrader.DegraderControl) URI(java.net.URI) CallCompletion(com.linkedin.util.degrader.CallCompletion) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) DegraderTrackerClientImpl(com.linkedin.d2.balancer.clients.DegraderTrackerClientImpl) RequestContext(com.linkedin.r2.message.RequestContext) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Aggregations

Test (org.testng.annotations.Test)8 DegraderTrackerClient (com.linkedin.d2.balancer.clients.DegraderTrackerClient)6 DegraderTrackerClientTest (com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)6 TrackerClient (com.linkedin.d2.balancer.clients.TrackerClient)6 RequestContext (com.linkedin.r2.message.RequestContext)6 URI (java.net.URI)5 ArrayList (java.util.ArrayList)5 HashMap (java.util.HashMap)5 DegraderTrackerClientImpl (com.linkedin.d2.balancer.clients.DegraderTrackerClientImpl)4 D2RingProperties (com.linkedin.d2.D2RingProperties)3 StringArray (com.linkedin.data.template.StringArray)3 CallCompletion (com.linkedin.util.degrader.CallCompletion)3 DegraderControl (com.linkedin.util.degrader.DegraderControl)3 ConsistentHashAlgorithm (com.linkedin.d2.ConsistentHashAlgorithm)2 D2LoadBalancerStrategyProperties (com.linkedin.d2.D2LoadBalancerStrategyProperties)2 D2QuarantineProperties (com.linkedin.d2.D2QuarantineProperties)2 D2RelativeStrategyProperties (com.linkedin.d2.D2RelativeStrategyProperties)2 HashConfig (com.linkedin.d2.HashConfig)2 HttpMethod (com.linkedin.d2.HttpMethod)2 HttpStatusCodeRange (com.linkedin.d2.HttpStatusCodeRange)2