use of com.linkedin.darkcluster.api.NoOpDarkClusterStrategy in project rest.li by linkedin.
the class TestDarkClusterStrategyFactory method testCreateStrategiesWithNoDarkClusters.
@Test
public void testCreateStrategiesWithNoDarkClusters() {
DarkClusterStrategy strategy = _strategyFactory.get(DARK_CLUSTER_NAME);
RestRequest dummyRestRequest = new RestRequestBuilder(URI.create("foo")).build();
boolean requestSent = strategy.handleRequest(dummyRestRequest, dummyRestRequest, new RequestContext());
Assert.assertTrue(strategy instanceof NoOpDarkClusterStrategy);
Assert.assertFalse(requestSent, "default empty strategy should not send request");
}
use of com.linkedin.darkcluster.api.NoOpDarkClusterStrategy in project rest.li by linkedin.
the class TestDarkClusterStrategyFactory method testStrategyFallThruWithNoFallback.
@Test
public void testStrategyFallThruWithNoFallback() {
DarkClusterConfig darkClusterConfig1 = createRelativeTrafficMultiplierConfig(0.5f);
DarkClusterStrategyNameArray darkClusterStrategyList = new DarkClusterStrategyNameArray();
// Only ConstantQPS strategy is present, with no alternative.
darkClusterStrategyList.addAll(Collections.singletonList(CONSTANT_QPS));
darkClusterConfig1.setDarkClusterStrategyPrioritizedList(darkClusterStrategyList);
_clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig1);
_clusterInfoProvider.notifyListenersClusterAdded(SOURCE_CLUSTER_NAME);
DarkClusterStrategy strategy = _strategyFactory.get(DARK_CLUSTER_NAME);
// test that we didn't find a strategy corresponding to Constant QPS and fell through. It will end up with the NoOpStrategy.
Assert.assertTrue(strategy instanceof NoOpDarkClusterStrategy);
}
use of com.linkedin.darkcluster.api.NoOpDarkClusterStrategy in project rest.li by linkedin.
the class TestDarkClusterStrategyFactory method testStrategyZeroMultiplier.
@Test
public void testStrategyZeroMultiplier() {
DarkClusterConfig darkClusterConfig1 = createRelativeTrafficMultiplierConfig(0f);
DarkClusterStrategyNameArray darkClusterStrategyList = new DarkClusterStrategyNameArray();
darkClusterStrategyList.addAll(Collections.singletonList(RELATIVE_TRAFFIC));
darkClusterConfig1.setDarkClusterStrategyPrioritizedList(darkClusterStrategyList);
_clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig1);
DarkClusterStrategy strategy = _strategyFactory.get(DARK_CLUSTER_NAME);
// test that we choose a NoOpDarkClusterStrategy because we want to allow RelativeTrafficMultiplierStrategy with a zero muliplier to be
// a NoOp. This allows clients to easily turn off traffic without adjusting multiple values.
Assert.assertTrue(strategy instanceof NoOpDarkClusterStrategy);
}
use of com.linkedin.darkcluster.api.NoOpDarkClusterStrategy 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();
}
}
use of com.linkedin.darkcluster.api.NoOpDarkClusterStrategy in project rest.li by linkedin.
the class DarkClusterStrategyFactoryImpl method createStrategy.
/**
* In the future, additional strategies can be added, and the logic here can choose the appropriate one based on the config values.
*/
private DarkClusterStrategy createStrategy(String darkClusterName, DarkClusterConfig darkClusterConfig) {
if (darkClusterConfig.hasDarkClusterStrategyPrioritizedList()) {
DarkClusterStrategyNameArray strategyList = darkClusterConfig.getDarkClusterStrategyPrioritizedList();
for (com.linkedin.d2.DarkClusterStrategyName darkClusterStrategyName : strategyList) {
switch(darkClusterStrategyName) {
case RELATIVE_TRAFFIC:
if (RelativeTrafficMultiplierDarkClusterStrategy.isValidConfig(darkClusterConfig)) {
BaseDarkClusterDispatcher baseDarkClusterDispatcher = new BaseDarkClusterDispatcherImpl(darkClusterName, _darkClusterDispatcher, _notifier, _verifierManager);
return new RelativeTrafficMultiplierDarkClusterStrategy(_sourceClusterName, darkClusterName, darkClusterConfig.getMultiplier(), baseDarkClusterDispatcher, _notifier, _facilities.getClusterInfoProvider(), _random);
}
break;
case IDENTICAL_TRAFFIC:
if (IdenticalTrafficMultiplierDarkClusterStrategy.isValidConfig(darkClusterConfig)) {
BaseDarkClusterDispatcher baseDarkClusterDispatcher = new BaseDarkClusterDispatcherImpl(darkClusterName, _darkClusterDispatcher, _notifier, _verifierManager);
return new IdenticalTrafficMultiplierDarkClusterStrategy(_sourceClusterName, darkClusterName, darkClusterConfig.getMultiplier(), baseDarkClusterDispatcher, _notifier, _facilities.getClusterInfoProvider(), _random);
}
break;
case CONSTANT_QPS:
if (_rateLimiterSupplier == null) {
LOG.error("Dark Cluster {} configured to use CONSTANT_QPS strategy, but no rate limiter provided during instantiation. " + "No Dark Cluster strategy will be used!", darkClusterName);
break;
}
if (ConstantQpsDarkClusterStrategy.isValidConfig(darkClusterConfig)) {
BaseDarkClusterDispatcher baseDarkClusterDispatcher = new BaseDarkClusterDispatcherImpl(darkClusterName, _darkClusterDispatcher, _notifier, _verifierManager);
ConstantQpsRateLimiter rateLimiter = _rateLimiterSupplier.get();
rateLimiter.setBufferCapacity(darkClusterConfig.getDispatcherMaxRequestsToBuffer());
rateLimiter.setBufferTtl(darkClusterConfig.getDispatcherBufferedRequestExpiryInSeconds(), ChronoUnit.SECONDS);
return new ConstantQpsDarkClusterStrategy(_sourceClusterName, darkClusterName, darkClusterConfig.getDispatcherOutboundTargetRate(), baseDarkClusterDispatcher, _notifier, _facilities.getClusterInfoProvider(), rateLimiter);
}
break;
default:
break;
}
}
}
return new NoOpDarkClusterStrategy();
}
Aggregations