Search in sources :

Example 21 with DEFAULT_PARTITION_ID

use of com.linkedin.d2.balancer.util.partitions.DefaultPartitionAccessor.DEFAULT_PARTITION_ID in project rest.li by linkedin.

the class StateUpdaterTest method testInitializePartitionWithDoNotLoadBalance.

@Test(dataProvider = "trueFalse")
public void testInitializePartitionWithDoNotLoadBalance(boolean doNotLoadBalance) {
    double initialHealthScore = 0.01;
    D2RelativeStrategyProperties relativeStrategyProperties = new D2RelativeStrategyProperties().setInitialHealthScore(initialHealthScore);
    setup(relativeStrategyProperties, new ConcurrentHashMap<>());
    List<TrackerClient> trackerClients = TrackerClientMockHelper.mockTrackerClients(2, Arrays.asList(20, 20), Arrays.asList(10, 10), Arrays.asList(200L, 500L), Arrays.asList(100L, 200L), Arrays.asList(0, 0), false, Arrays.asList(false, doNotLoadBalance));
    assertTrue(_stateUpdater.getPointsMap(DEFAULT_PARTITION_ID).isEmpty(), "There should be no state before initialization");
    _stateUpdater.updateState(new HashSet<>(trackerClients), DEFAULT_PARTITION_ID, DEFAULT_CLUSTER_GENERATION_ID, false);
    final TrackerClient trackerClient0 = trackerClients.get(0);
    final TrackerClient trackerClient1 = trackerClients.get(1);
    assertTrackerClientState(DEFAULT_PARTITION_ID, trackerClient0, (int) (initialHealthScore * RelativeLoadBalancerStrategyFactory.DEFAULT_POINTS_PER_WEIGHT), false);
    if (!doNotLoadBalance) {
        assertTrackerClientState(DEFAULT_PARTITION_ID, trackerClient1, (int) (initialHealthScore * RelativeLoadBalancerStrategyFactory.DEFAULT_POINTS_PER_WEIGHT), false);
    } else {
        assertTrackerClientState(DEFAULT_PARTITION_ID, trackerClient1, HEALTHY_POINTS, false);
    }
}
Also used : TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) D2RelativeStrategyProperties(com.linkedin.d2.D2RelativeStrategyProperties) Test(org.testng.annotations.Test)

Example 22 with DEFAULT_PARTITION_ID

use of com.linkedin.d2.balancer.util.partitions.DefaultPartitionAccessor.DEFAULT_PARTITION_ID in project rest.li by linkedin.

the class StateUpdaterTest method testInitializePartitionWithMultipleThreads.

@Test
public void testInitializePartitionWithMultipleThreads() throws InterruptedException {
    setup(new D2RelativeStrategyProperties(), new ConcurrentHashMap<>());
    List<TrackerClient> trackerClients = TrackerClientMockHelper.mockTrackerClients(2, Arrays.asList(20, 20), Arrays.asList(10, 10), Arrays.asList(200L, 500L), Arrays.asList(100L, 200L), Arrays.asList(0, 0));
    assertTrue(_stateUpdater.getPointsMap(DEFAULT_PARTITION_ID).isEmpty(), "There should be no state before initialization");
    int numThreads = 50;
    ExecutorService executorService = Executors.newFixedThreadPool(numThreads);
    CountDownLatch countDownLatch = new CountDownLatch(numThreads);
    Runnable runnable = () -> {
        PartitionState lastState = _stateUpdater.getPartitionState(DEFAULT_PARTITION_ID);
        _stateUpdater.updateState(new HashSet<>(trackerClients), DEFAULT_PARTITION_ID, DEFAULT_CLUSTER_GENERATION_ID, false);
        PartitionState currentState = _stateUpdater.getPartitionState(DEFAULT_PARTITION_ID);
        if (lastState != null) {
            assertEquals(currentState, lastState, "The partition state should always be the same object created by the first thread that obtained the lock");
        }
    };
    for (int threadIndex = 0; threadIndex < numThreads; threadIndex++) {
        runIndividualConcurrentTask(executorService, runnable, countDownLatch);
    }
    if (!countDownLatch.await(2, TimeUnit.SECONDS)) {
        fail("Initialization failed to finish within 2 seconds");
    }
    assertEquals(_stateUpdater.getPointsMap(DEFAULT_PARTITION_ID).get(trackerClients.get(0).getUri()).intValue(), HEALTHY_POINTS);
    assertEquals(_stateUpdater.getPointsMap(DEFAULT_PARTITION_ID).get(trackerClients.get(1).getUri()).intValue(), HEALTHY_POINTS);
    executorService.shutdown();
}
Also used : TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ExecutorService(java.util.concurrent.ExecutorService) CountDownLatch(java.util.concurrent.CountDownLatch) D2RelativeStrategyProperties(com.linkedin.d2.D2RelativeStrategyProperties) HashSet(java.util.HashSet) Test(org.testng.annotations.Test)

Example 23 with DEFAULT_PARTITION_ID

use of com.linkedin.d2.balancer.util.partitions.DefaultPartitionAccessor.DEFAULT_PARTITION_ID in project rest.li by linkedin.

the class StateUpdaterTest method testUpdateOnePartition.

@Test
public void testUpdateOnePartition() {
    List<TrackerClient> trackerClients = TrackerClientMockHelper.mockTrackerClients(3, Arrays.asList(20, 20, 20), Arrays.asList(10, 10, 10), Arrays.asList(200L, 300L, 1000L), Arrays.asList(100L, 200L, 500L), Arrays.asList(0, 0, 0));
    PartitionState state = new PartitionStateTestDataBuilder().setClusterGenerationId(DEFAULT_CLUSTER_GENERATION_ID).setTrackerClientStateMap(trackerClients, Arrays.asList(1.0, 1.0, 1.0), Arrays.asList(TrackerClientState.HealthState.HEALTHY, TrackerClientState.HealthState.HEALTHY, TrackerClientState.HealthState.HEALTHY), Arrays.asList(30, 30, 30)).build();
    ConcurrentMap<Integer, PartitionState> partitionLoadBalancerStateMap = new ConcurrentHashMap<>();
    partitionLoadBalancerStateMap.put(DEFAULT_PARTITION_ID, state);
    setup(new D2RelativeStrategyProperties(), partitionLoadBalancerStateMap);
    _stateUpdater.updateState();
    Map<URI, Integer> pointsMap = _stateUpdater.getPointsMap(DEFAULT_PARTITION_ID);
    assertEquals(pointsMap.get(trackerClients.get(0).getUri()).intValue(), HEALTHY_POINTS);
    assertEquals(pointsMap.get(trackerClients.get(1).getUri()).intValue(), HEALTHY_POINTS);
    assertEquals(pointsMap.get(trackerClients.get(2).getUri()).intValue(), (int) (HEALTHY_POINTS - RelativeLoadBalancerStrategyFactory.DEFAULT_DOWN_STEP * RelativeLoadBalancerStrategyFactory.DEFAULT_POINTS_PER_WEIGHT));
}
Also used : TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) URI(java.net.URI) D2RelativeStrategyProperties(com.linkedin.d2.D2RelativeStrategyProperties) Test(org.testng.annotations.Test)

Example 24 with DEFAULT_PARTITION_ID

use of com.linkedin.d2.balancer.util.partitions.DefaultPartitionAccessor.DEFAULT_PARTITION_ID in project rest.li by linkedin.

the class StateUpdaterTest method testExecutorSchedule.

@Test
public void testExecutorSchedule() throws InterruptedException {
    setup(new D2RelativeStrategyProperties(), new ConcurrentHashMap<>());
    List<TrackerClient> trackerClients = TrackerClientMockHelper.mockTrackerClients(2, Arrays.asList(20, 20), Arrays.asList(10, 10), Arrays.asList(200L, 200L), Arrays.asList(100L, 100L), Arrays.asList(0, 0));
    PartitionState existingState = new PartitionStateTestDataBuilder().setTrackerClientStateMap(trackerClients, Arrays.asList(1.0, 1.0), Arrays.asList(TrackerClientState.HealthState.HEALTHY, TrackerClientState.HealthState.HEALTHY), Arrays.asList(30, 30)).build();
    ConcurrentMap<Integer, PartitionState> stateMap = new ConcurrentHashMap<>();
    stateMap.put(DEFAULT_PARTITION_ID, existingState);
    ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    D2RelativeStrategyProperties relativeStrategyProperties = RelativeLoadBalancerStrategyFactory.putDefaultValues(new D2RelativeStrategyProperties());
    _stateUpdater = new StateUpdater(relativeStrategyProperties, _quarantineManager, executorService, stateMap, Collections.emptyList(), SERVICE_NAME);
    // In 6 seconds, the update should be executed twice
    CountDownLatch countDownLatch = new CountDownLatch(2);
    Mockito.doAnswer(new ExecutionCountDown<>(countDownLatch)).when(_quarantineManager).updateQuarantineState(any(), any(), anyLong());
    if (!countDownLatch.await(6, TimeUnit.SECONDS)) {
        fail("scheduled update failed to finish within 6 seconds");
    }
    Mockito.verify(_quarantineManager, Mockito.atLeast(2)).updateQuarantineState(any(), any(), anyLong());
    assertEquals(_stateUpdater.getPointsMap(DEFAULT_PARTITION_ID).get(trackerClients.get(0).getUri()).intValue(), HEALTHY_POINTS);
    assertEquals(_stateUpdater.getPointsMap(DEFAULT_PARTITION_ID).get(trackerClients.get(1).getUri()).intValue(), HEALTHY_POINTS);
    executorService.shutdown();
}
Also used : ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) CountDownLatch(java.util.concurrent.CountDownLatch) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) D2RelativeStrategyProperties(com.linkedin.d2.D2RelativeStrategyProperties) Test(org.testng.annotations.Test)

Example 25 with DEFAULT_PARTITION_ID

use of com.linkedin.d2.balancer.util.partitions.DefaultPartitionAccessor.DEFAULT_PARTITION_ID in project rest.li by linkedin.

the class DegraderLoadBalancerTest method testHighLowWatermarks.

@Test(groups = { "small", "back-end" })
public void testHighLowWatermarks() {
    final int NUM_CHECKS = 5;
    Map<String, Object> myMap = lbDefaultConfig();
    Long timeInterval = 5000L;
    double globalStepUp = 0.4;
    double globalStepDown = 0.4;
    double highWaterMark = 1000;
    double lowWaterMark = 50;
    TestClock clock = new TestClock();
    myMap.put(PropertyKeys.CLOCK, clock);
    myMap.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_INTERVAL_MS, timeInterval);
    myMap.put(PropertyKeys.HTTP_LB_GLOBAL_STEP_UP, globalStepUp);
    myMap.put(PropertyKeys.HTTP_LB_GLOBAL_STEP_DOWN, globalStepDown);
    myMap.put(PropertyKeys.HTTP_LB_HIGH_WATER_MARK, highWaterMark);
    myMap.put(PropertyKeys.HTTP_LB_LOW_WATER_MARK, lowWaterMark);
    myMap.put(PropertyKeys.HTTP_LB_CLUSTER_MIN_CALL_COUNT_HIGH_WATER_MARK, 1l);
    myMap.put(PropertyKeys.HTTP_LB_CLUSTER_MIN_CALL_COUNT_LOW_WATER_MARK, 1l);
    DegraderLoadBalancerStrategyConfig config = DegraderLoadBalancerStrategyConfig.createHttpConfigFromMap(myMap);
    DegraderLoadBalancerStrategyV3 strategy = new DegraderLoadBalancerStrategyV3(config, "DegraderLoadBalancerTest", null, DEGRADER_STATE_LISTENER_FACTORIES);
    List<DegraderTrackerClient> clients = new ArrayList<>();
    URI uri1 = URI.create("http://test.linkedin.com:3242/fdsaf");
    URIRequest request = new URIRequest(uri1);
    DegraderTrackerClient client1 = new DegraderTrackerClientImpl(uri1, getDefaultPartitionData(1d), new TestLoadBalancerClient(uri1), clock, null);
    clients.add(client1);
    DegraderControl dcClient1Default = client1.getDegraderControl(DEFAULT_PARTITION_ID);
    dcClient1Default.setOverrideMinCallCount(5);
    dcClient1Default.setMinCallCount(5);
    List<CallCompletion> ccList = new ArrayList<>();
    CallCompletion cc;
    TrackerClient resultTC = getTrackerClient(strategy, request, new RequestContext(), 1, clients);
    // The override drop rate should be zero at this point.
    assertEquals(dcClient1Default.getOverrideDropRate(), 0.0);
    // make high latency calls to the tracker client, verify the override drop rate doesn't change
    for (int j = 0; j < NUM_CHECKS; j++) {
        cc = client1.getCallTracker().startCall();
        ccList.add(cc);
    }
    clock.addMs((long) highWaterMark);
    for (Iterator<CallCompletion> iter = ccList.listIterator(); iter.hasNext(); ) {
        cc = iter.next();
        cc.endCall();
        iter.remove();
    }
    // go to next time interval.
    clock.addMs(timeInterval);
    // try call dropping on the next updateState
    strategy.setStrategy(DEFAULT_PARTITION_ID, PartitionDegraderLoadBalancerState.Strategy.CALL_DROPPING);
    resultTC = getTrackerClient(strategy, request, new RequestContext(), 1, clients);
    // we now expect that the override drop rate stepped up because updateState
    // made that decision.
    assertEquals(dcClient1Default.getOverrideDropRate(), globalStepUp);
    // make mid latency calls to the tracker client, verify the override drop rate doesn't change
    for (int j = 0; j < NUM_CHECKS; j++) {
        // need to use client1 because the resultTC may be null
        cc = client1.getCallTracker().startCall();
        ccList.add(cc);
    }
    clock.addMs((long) highWaterMark - 1);
    for (Iterator<CallCompletion> iter = ccList.listIterator(); iter.hasNext(); ) {
        cc = iter.next();
        cc.endCall();
        iter.remove();
    }
    // go to next time interval.
    clock.addMs(timeInterval);
    double previousOverrideDropRate = dcClient1Default.getOverrideDropRate();
    // try call dropping on the next updateState
    strategy.setStrategy(DEFAULT_PARTITION_ID, PartitionDegraderLoadBalancerState.Strategy.CALL_DROPPING);
    resultTC = getTrackerClient(strategy, request, new RequestContext(), 1, clients);
    assertEquals(dcClient1Default.getOverrideDropRate(), previousOverrideDropRate);
    // make low latency calls to the tracker client, verify the override drop rate decreases
    for (int j = 0; j < NUM_CHECKS; j++) {
        cc = client1.getCallTracker().startCall();
        ccList.add(cc);
    }
    clock.addMs((long) lowWaterMark);
    for (Iterator<CallCompletion> iter = ccList.listIterator(); iter.hasNext(); ) {
        cc = iter.next();
        cc.endCall();
        iter.remove();
    }
    // go to next time interval.
    clock.addMs(timeInterval);
    // try Call dropping on this updateState
    strategy.setStrategy(DEFAULT_PARTITION_ID, PartitionDegraderLoadBalancerState.Strategy.CALL_DROPPING);
    resultTC = getTrackerClient(strategy, request, new RequestContext(), 1, clients);
    assertEquals(((DegraderTrackerClient) resultTC).getDegraderControl(DEFAULT_PARTITION_ID).getOverrideDropRate(), 0.0);
}
Also used : DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) ArrayList(java.util.ArrayList) URIRequest(com.linkedin.d2.balancer.util.URIRequest) 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) AtomicLong(java.util.concurrent.atomic.AtomicLong) 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)32 TrackerClient (com.linkedin.d2.balancer.clients.TrackerClient)30 URI (java.net.URI)28 ArrayList (java.util.ArrayList)26 DegraderTrackerClient (com.linkedin.d2.balancer.clients.DegraderTrackerClient)21 RequestContext (com.linkedin.r2.message.RequestContext)19 DegraderTrackerClientTest (com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)17 DegraderControl (com.linkedin.util.degrader.DegraderControl)12 HashMap (java.util.HashMap)12 URIRequest (com.linkedin.d2.balancer.util.URIRequest)11 D2RelativeStrategyProperties (com.linkedin.d2.D2RelativeStrategyProperties)10 CallCompletion (com.linkedin.util.degrader.CallCompletion)10 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)9 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)7 AtomicLong (java.util.concurrent.atomic.AtomicLong)7 DegraderTrackerClientImpl (com.linkedin.d2.balancer.clients.DegraderTrackerClientImpl)6 HashSet (java.util.HashSet)6 CountDownLatch (java.util.concurrent.CountDownLatch)6 FutureCallback (com.linkedin.common.callback.FutureCallback)5 None (com.linkedin.common.util.None)5