Search in sources :

Example 6 with RelativeTrafficMultiplierDarkClusterStrategy

use of com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy 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 7 with RelativeTrafficMultiplierDarkClusterStrategy

use of com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy 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 8 with RelativeTrafficMultiplierDarkClusterStrategy

use of com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy in project rest.li by linkedin.

the class TestRelativeTrafficMultiplierDarkClusterStrategy method testStrategy.

@Test(dataProvider = "multiplierKeys")
public void testStrategy(int numIterations, float multiplier, int numSourceInstances, int numDarkInstances) {
    DarkClusterDispatcher darkClusterDispatcher = new DefaultDarkClusterDispatcher(new MockClient(false));
    BaseDarkClusterDispatcherImpl baseDispatcher = new BaseDarkClusterDispatcherImpl(DARK_CLUSTER_NAME, darkClusterDispatcher, new DoNothingNotifier(), new CountingVerifierManager());
    MockClusterInfoProvider mockClusterInfoProvider = new MockClusterInfoProvider();
    mockClusterInfoProvider.putHttpsClusterCount(DARK_CLUSTER_NAME, numDarkInstances);
    mockClusterInfoProvider.putHttpsClusterCount(SOURCE_CLUSTER_NAME, numSourceInstances);
    RelativeTrafficMultiplierDarkClusterStrategy strategy = new RelativeTrafficMultiplierDarkClusterStrategy(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, multiplier, baseDispatcher, new DoNothingNotifier(), mockClusterInfoProvider, new Random(SEED));
    for (int i = 0; i < numIterations; i++) {
        RestRequest dummyRestRequest = new RestRequestBuilder(URI.create("foo")).build();
        strategy.handleRequest(dummyRestRequest, dummyRestRequest, new RequestContext());
    }
    int expectedCount = (int) (numIterations * multiplier * numDarkInstances) / (numSourceInstances);
    int actualCount = baseDispatcher.getRequestCount();
    Assert.assertEquals(actualCount, expectedCount, expectedCount * ERR_PCT, "count not within expected range");
}
Also used : RelativeTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy) DefaultDarkClusterDispatcher(com.linkedin.darkcluster.impl.DefaultDarkClusterDispatcher) DarkClusterDispatcher(com.linkedin.darkcluster.api.DarkClusterDispatcher) DefaultDarkClusterDispatcher(com.linkedin.darkcluster.impl.DefaultDarkClusterDispatcher) 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

RelativeTrafficMultiplierDarkClusterStrategy (com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy)8 Test (org.testng.annotations.Test)8 DarkClusterStrategy (com.linkedin.darkcluster.api.DarkClusterStrategy)7 NoOpDarkClusterStrategy (com.linkedin.darkcluster.api.NoOpDarkClusterStrategy)7 DarkClusterConfig (com.linkedin.d2.DarkClusterConfig)6 RequestContext (com.linkedin.r2.message.RequestContext)2 RestRequest (com.linkedin.r2.message.rest.RestRequest)2 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)2 DarkClusterStrategyNameArray (com.linkedin.d2.DarkClusterStrategyNameArray)1 DarkClusterDispatcher (com.linkedin.darkcluster.api.DarkClusterDispatcher)1 BaseDarkClusterDispatcherImpl (com.linkedin.darkcluster.impl.BaseDarkClusterDispatcherImpl)1 DefaultDarkClusterDispatcher (com.linkedin.darkcluster.impl.DefaultDarkClusterDispatcher)1 Random (java.util.Random)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)1