Search in sources :

Example 11 with DarkClusterStrategy

use of com.linkedin.darkcluster.api.DarkClusterStrategy in project rest.li by linkedin.

the class TestDarkClusterStrategyFactory method testNoChangeStrategyOnNotification.

@Test
public void testNoChangeStrategyOnNotification() {
    DarkClusterConfig darkClusterConfig1 = createRelativeTrafficMultiplierConfig(0.5f);
    DarkClusterConfig darkClusterConfig2 = createRelativeTrafficMultiplierConfig(1.0f);
    _clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig1);
    _clusterInfoProvider.notifyListenersClusterAdded(SOURCE_CLUSTER_NAME);
    DarkClusterStrategy strategy = _strategyFactory.get(DARK_CLUSTER_NAME);
    Assert.assertTrue(strategy instanceof RelativeTrafficMultiplierDarkClusterStrategy);
    Assert.assertEquals(((RelativeTrafficMultiplierDarkClusterStrategy) strategy).getMultiplier(), 0.5f, "expected 0.5f multiplier");
    // update Strategy, then simulating a notification on the dark cluster.
    _clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig2);
    _clusterInfoProvider.notifyListenersClusterAdded(DARK_CLUSTER_NAME);
    // Nothing should have been changed, since we should be ignoring dark cluster changes. (strategy-impacting changes are all captured
    // in the source cluster data)
    DarkClusterStrategy strategy2 = _strategyFactory.get(DARK_CLUSTER_NAME);
    Assert.assertTrue(strategy2 instanceof RelativeTrafficMultiplierDarkClusterStrategy);
    Assert.assertEquals(((RelativeTrafficMultiplierDarkClusterStrategy) strategy2).getMultiplier(), 0.5f, "expected 0.5f multiplier");
}
Also used : RelativeTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy) DarkClusterConfig(com.linkedin.d2.DarkClusterConfig) NoOpDarkClusterStrategy(com.linkedin.darkcluster.api.NoOpDarkClusterStrategy) RelativeTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy) DarkClusterStrategy(com.linkedin.darkcluster.api.DarkClusterStrategy) Test(org.testng.annotations.Test)

Example 12 with DarkClusterStrategy

use of com.linkedin.darkcluster.api.DarkClusterStrategy in project rest.li by linkedin.

the class TestDarkClusterStrategyFactory method testStrategyRaceCondition.

@Test
public void testStrategyRaceCondition() {
    int noopStrategyCount = 0;
    DarkClusterConfig darkClusterConfig1 = createRelativeTrafficMultiplierConfig(0.5f);
    _clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig1);
    _clusterInfoProvider.notifyListenersClusterAdded(SOURCE_CLUSTER_NAME);
    DarkClusterStrategy strategy = _strategyFactory.get(DARK_CLUSTER_NAME);
    Assert.assertTrue(strategy instanceof RelativeTrafficMultiplierDarkClusterStrategy);
    Assert.assertEquals(((RelativeTrafficMultiplierDarkClusterStrategy) strategy).getMultiplier(), 0.5f, "expected 0.5f multiplier");
    // this was registered after DarkClusterStrategyFactoryImpl registered it's clusterListener.
    _clusterInfoProvider.registerClusterListener(new DeletingClusterListener(_clusterInfoProvider));
    ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
    final CountDownLatch latch = new CountDownLatch(1);
    try {
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            _clusterInfoProvider.notifyListenersClusterAdded(SOURCE_CLUSTER_NAME);
            latch.countDown();
        }, 0, 1, TimeUnit.MILLISECONDS);
        if (!latch.await(30, TimeUnit.SECONDS)) {
            fail("unable to execute task on executor");
        }
        for (int i = 0; i < 100000; i++) {
            strategy = _strategyFactory.get(DARK_CLUSTER_NAME);
            // verified that this will catch race conditions, saw it happen 9/100k times.
            Assert.assertNotNull(strategy, "null at iteration: " + i);
            if (strategy instanceof NoOpDarkClusterStrategy) {
                noopStrategyCount++;
            }
        }
        System.out.println("noopStrategyCount: " + noopStrategyCount);
    } catch (InterruptedException ie) {
        fail("got interrupted exception", ie);
    } finally {
        scheduledExecutorService.shutdown();
    }
}
Also used : ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) RelativeTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy) DarkClusterConfig(com.linkedin.d2.DarkClusterConfig) NoOpDarkClusterStrategy(com.linkedin.darkcluster.api.NoOpDarkClusterStrategy) RelativeTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy) DarkClusterStrategy(com.linkedin.darkcluster.api.DarkClusterStrategy) CountDownLatch(java.util.concurrent.CountDownLatch) NoOpDarkClusterStrategy(com.linkedin.darkcluster.api.NoOpDarkClusterStrategy) Test(org.testng.annotations.Test)

Example 13 with DarkClusterStrategy

use of com.linkedin.darkcluster.api.DarkClusterStrategy in project rest.li by linkedin.

the class TestIdenticalTrafficMultiplierDarkClusterStrategy method testHandleRequest.

@Test(dataProvider = "getDarkClusters")
public void testHandleRequest(List<DarkClusterMetadata> darkClusterMetadataList, float expectedRandomNumber) {
    String sourceClusterName = "sourceCluster";
    DarkClusterDispatcher darkClusterDispatcher = new DefaultDarkClusterDispatcher(new MockClient(false));
    Random random = Mockito.mock(Random.class);
    Mockito.when(random.nextFloat()).thenReturn(expectedRandomNumber);
    List<IdenticalTrafficMultiplierDarkClusterStrategy> strategies = darkClusterMetadataList.stream().map(darkClusterMetadata -> {
        BaseDarkClusterDispatcherImpl baseDispatcher = new BaseDarkClusterDispatcherImpl(darkClusterMetadata._darkClusterName, darkClusterDispatcher, new DoNothingNotifier(), new CountingVerifierManager());
        MockClusterInfoProvider mockClusterInfoProvider = new MockClusterInfoProvider();
        mockClusterInfoProvider.putHttpsClusterCount(darkClusterMetadata._darkClusterName, 1);
        mockClusterInfoProvider.putHttpsClusterCount(sourceClusterName, 1);
        return new IdenticalTrafficMultiplierDarkClusterStrategy(sourceClusterName, darkClusterMetadata._darkClusterName, darkClusterMetadata._multiplier, baseDispatcher, new DoNothingNotifier(), mockClusterInfoProvider, random);
    }).collect(Collectors.toList());
    RestRequest dummyRestRequest = new RestRequestBuilder(URI.create("foo")).build();
    RestRequest dummyDarkRequest = new RestRequestBuilder(URI.create("darkfoo")).build();
    RequestContext dummyRequestContext = new RequestContext();
    IntStream.range(0, darkClusterMetadataList.size()).forEach(index -> {
        DarkClusterMetadata darkClusterMetadata = darkClusterMetadataList.get(index);
        DarkClusterStrategy strategy = strategies.get(index);
        boolean darkRequestSent = strategy.handleRequest(dummyRestRequest, dummyDarkRequest, dummyRequestContext);
        Assert.assertEquals(darkRequestSent, darkClusterMetadata._darkRequestSent);
    });
    Assert.assertEquals(dummyRequestContext.getLocalAttr("identicalTrafficMultiplier.randomNumber"), expectedRandomNumber);
    Mockito.verify(random).nextFloat();
}
Also used : IntStream(java.util.stream.IntStream) DarkClusterStrategy(com.linkedin.darkcluster.api.DarkClusterStrategy) RestRequest(com.linkedin.r2.message.rest.RestRequest) Arrays(java.util.Arrays) DataProvider(org.testng.annotations.DataProvider) IdenticalTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.IdenticalTrafficMultiplierDarkClusterStrategy) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) Random(java.util.Random) Test(org.testng.annotations.Test) Collectors(java.util.stream.Collectors) Mockito(org.mockito.Mockito) BaseDarkClusterDispatcherImpl(com.linkedin.darkcluster.impl.BaseDarkClusterDispatcherImpl) List(java.util.List) RequestContext(com.linkedin.r2.message.RequestContext) Assert(org.testng.Assert) DarkClusterDispatcher(com.linkedin.darkcluster.api.DarkClusterDispatcher) URI(java.net.URI) DefaultDarkClusterDispatcher(com.linkedin.darkcluster.impl.DefaultDarkClusterDispatcher) DefaultDarkClusterDispatcher(com.linkedin.darkcluster.impl.DefaultDarkClusterDispatcher) IdenticalTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.IdenticalTrafficMultiplierDarkClusterStrategy) DarkClusterDispatcher(com.linkedin.darkcluster.api.DarkClusterDispatcher) DefaultDarkClusterDispatcher(com.linkedin.darkcluster.impl.DefaultDarkClusterDispatcher) DarkClusterStrategy(com.linkedin.darkcluster.api.DarkClusterStrategy) IdenticalTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.IdenticalTrafficMultiplierDarkClusterStrategy) RestRequest(com.linkedin.r2.message.rest.RestRequest) Random(java.util.Random) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) BaseDarkClusterDispatcherImpl(com.linkedin.darkcluster.impl.BaseDarkClusterDispatcherImpl) Test(org.testng.annotations.Test)

Aggregations

DarkClusterStrategy (com.linkedin.darkcluster.api.DarkClusterStrategy)13 Test (org.testng.annotations.Test)12 NoOpDarkClusterStrategy (com.linkedin.darkcluster.api.NoOpDarkClusterStrategy)11 RelativeTrafficMultiplierDarkClusterStrategy (com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy)10 DarkClusterConfig (com.linkedin.d2.DarkClusterConfig)9 RequestContext (com.linkedin.r2.message.RequestContext)5 RestRequest (com.linkedin.r2.message.rest.RestRequest)5 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)4 DarkClusterStrategyNameArray (com.linkedin.d2.DarkClusterStrategyNameArray)3 DarkClusterConfigMap (com.linkedin.d2.DarkClusterConfigMap)1 Facilities (com.linkedin.d2.balancer.Facilities)1 DarkClusterDispatcher (com.linkedin.darkcluster.api.DarkClusterDispatcher)1 DarkClusterManager (com.linkedin.darkcluster.api.DarkClusterManager)1 DarkClusterStrategyFactory (com.linkedin.darkcluster.api.DarkClusterStrategyFactory)1 DarkRequestHeaderGenerator (com.linkedin.darkcluster.api.DarkRequestHeaderGenerator)1 BaseDarkClusterDispatcherImpl (com.linkedin.darkcluster.impl.BaseDarkClusterDispatcherImpl)1 DarkClusterManagerImpl (com.linkedin.darkcluster.impl.DarkClusterManagerImpl)1 DefaultDarkClusterDispatcher (com.linkedin.darkcluster.impl.DefaultDarkClusterDispatcher)1 IdenticalTrafficMultiplierDarkClusterStrategy (com.linkedin.darkcluster.impl.IdenticalTrafficMultiplierDarkClusterStrategy)1 URI (java.net.URI)1