Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing the resettability of HystrixMetricsPublisherFactory #457

Merged
merged 1 commit into from
Jan 8, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.concurrent.TimeUnit;

import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisherFactory;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHookDefault;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisherDefault;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisherFactory;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategyDefault;

Expand Down Expand Up @@ -64,6 +65,7 @@ public static void reset() {
getInstance().metricsPublisher.set(null);
getInstance().propertiesFactory.set(null);
getInstance().commandExecutionHook.set(null);
HystrixMetricsPublisherFactory.reset();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.netflix.hystrix.strategy.metrics;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;

import com.netflix.hystrix.HystrixCircuitBreaker;
import com.netflix.hystrix.HystrixCommand;
Expand Down Expand Up @@ -81,30 +82,16 @@ public static HystrixMetricsPublisherCommand createOrRetrievePublisherForCommand

/**
* Resets the SINGLETON object.
*
*/
/* package */ static void reset() {
SINGLETON = new HystrixMetricsPublisherFactory();
}

/**
* Clears all state from publishers. If new requests come in instances will be recreated.
*
*/
/* package */ void _reset() {
commandPublishers.clear();
threadPoolPublishers.clear();
}

private final HystrixMetricsPublisher strategy;

private HystrixMetricsPublisherFactory() {
this(HystrixPlugins.getInstance().getMetricsPublisher());
public static void reset() {
SINGLETON = new HystrixMetricsPublisherFactory();
SINGLETON.commandPublishers.clear();
SINGLETON.threadPoolPublishers.clear();
}

/* package */ HystrixMetricsPublisherFactory(HystrixMetricsPublisher strategy) {
this.strategy = strategy;
}
/* package */ HystrixMetricsPublisherFactory() {}

// String is CommandKey.name() (we can't use CommandKey directly as we can't guarantee it implements hashcode/equals correctly)
private final ConcurrentHashMap<String, HystrixMetricsPublisherCommand> commandPublishers = new ConcurrentHashMap<String, HystrixMetricsPublisherCommand>();
Expand All @@ -116,7 +103,7 @@ private HystrixMetricsPublisherFactory() {
return publisher;
}
// it doesn't exist so we need to create it
publisher = strategy.getMetricsPublisherForCommand(commandKey, commandOwner, metrics, circuitBreaker, properties);
publisher = HystrixPlugins.getInstance().getMetricsPublisher().getMetricsPublisherForCommand(commandKey, commandOwner, metrics, circuitBreaker, properties);
// attempt to store it (race other threads)
HystrixMetricsPublisherCommand existing = commandPublishers.putIfAbsent(commandKey.name(), publisher);
if (existing == null) {
Expand All @@ -141,7 +128,7 @@ private HystrixMetricsPublisherFactory() {
return publisher;
}
// it doesn't exist so we need to create it
publisher = strategy.getMetricsPublisherForThreadPool(threadPoolKey, metrics, properties);
publisher = HystrixPlugins.getInstance().getMetricsPublisher().getMetricsPublisherForThreadPool(threadPoolKey, metrics, properties);
// attempt to store it (race other threads)
HystrixMetricsPublisherThreadPool existing = threadPoolPublishers.putIfAbsent(threadPoolKey.name(), publisher);
if (existing == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,12 @@ public HystrixThreadPoolMetrics getHystrixThreadPoolMetrics() {

@Test
public void ensureThreadPoolInstanceIsTheOneRegisteredWithMetricsPublisherAndThreadPoolCache() throws IllegalAccessException, NoSuchFieldException {
new HystrixPluginsTest().reset();
HystrixPlugins.getInstance().registerMetricsPublisher(new HystrixMetricsPublisher() {
@Override
public HystrixMetricsPublisherThreadPool getMetricsPublisherForThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolMetrics metrics, HystrixThreadPoolProperties properties) {
return new HystrixMetricsPublisherThreadPoolContainer(metrics);
}
});
new HystrixMetricsPublisherFactoryTest().reset();
HystrixThreadPoolKey threadPoolKey = HystrixThreadPoolKey.Factory.asKey("threadPoolFactoryConcurrencyTest");
HystrixThreadPool poolOne = new HystrixThreadPool.HystrixThreadPoolDefault(
threadPoolKey, HystrixThreadPoolProperties.Setter.getUnitTestPropertiesBuilder());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,7 @@
public class HystrixPluginsTest {
@After
public void reset() {
// use private access to reset so we can test different initializations via the public static flow
HystrixPlugins.getInstance().concurrencyStrategy.set(null);
HystrixPlugins.getInstance().metricsPublisher.set(null);
HystrixPlugins.getInstance().notifier.set(null);
HystrixPlugins.getInstance().propertiesFactory.set(null);
HystrixPlugins.getInstance().commandExecutionHook.set(null);
HystrixPlugins.reset();
}

@Test
Expand Down Expand Up @@ -241,5 +236,4 @@ protected Void run() throws Exception {
return null;
}
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.netflix.hystrix.strategy.metrics;

import static junit.framework.Assert.assertNotSame;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;

import com.netflix.hystrix.strategy.HystrixPlugins;
import org.junit.Before;
import org.junit.Test;

Expand All @@ -20,7 +23,7 @@
public class HystrixMetricsPublisherFactoryTest {
@Before
public void reset() {
HystrixMetricsPublisherFactory.reset();
HystrixPlugins.reset();
}

/**
Expand All @@ -29,7 +32,8 @@ public void reset() {
@Test
public void testSingleInitializePerKey() {
final TestHystrixMetricsPublisher publisher = new TestHystrixMetricsPublisher();
final HystrixMetricsPublisherFactory factory = new HystrixMetricsPublisherFactory(publisher);
HystrixPlugins.getInstance().registerMetricsPublisher(publisher);
final HystrixMetricsPublisherFactory factory = new HystrixMetricsPublisherFactory();
ArrayList<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 20; i++) {
threads.add(new Thread(new Runnable() {
Expand Down Expand Up @@ -63,6 +67,32 @@ public void run() {
assertEquals(1, publisher.threadCounter.get());
}

@Test
public void testMetricsPublisherReset() {
// precondition: HystrixMetricsPublisherFactory class is not loaded. Calling HystrixPlugins.reset() here should be good enough to run this with other tests.

// set first custom publisher
HystrixCommandKey key = HystrixCommandKey.Factory.asKey("key");
HystrixMetricsPublisherCommand firstCommand = new HystrixMetricsPublisherCommandDefault(key, null, null, null, null);
HystrixMetricsPublisher firstPublisher = new CustomPublisher(firstCommand);
HystrixPlugins.getInstance().registerMetricsPublisher(firstPublisher);

// ensure that first custom publisher is used
HystrixMetricsPublisherCommand cmd = HystrixMetricsPublisherFactory.createOrRetrievePublisherForCommand(key, null, null, null, null);
assertSame(firstCommand, cmd);

// reset, then change to second custom publisher
HystrixPlugins.reset();
HystrixMetricsPublisherCommand secondCommand = new HystrixMetricsPublisherCommandDefault(key, null, null, null, null);
HystrixMetricsPublisher secondPublisher = new CustomPublisher(secondCommand);
HystrixPlugins.getInstance().registerMetricsPublisher(secondPublisher);

// ensure that second custom publisher is used
cmd = HystrixMetricsPublisherFactory.createOrRetrievePublisherForCommand(key, null, null, null, null);
assertNotSame(firstCommand, cmd);
assertSame(secondCommand, cmd);
}

private static class TestHystrixMetricsPublisher extends HystrixMetricsPublisher {

AtomicInteger commandCounter = new AtomicInteger();
Expand Down Expand Up @@ -97,4 +127,16 @@ private static enum TestCommandKey implements HystrixCommandKey {
private static enum TestThreadPoolKey implements HystrixThreadPoolKey {
TEST_A, TEST_B;
}

static class CustomPublisher extends HystrixMetricsPublisher{
private HystrixMetricsPublisherCommand commandToReturn;
public CustomPublisher(HystrixMetricsPublisherCommand commandToReturn){
this.commandToReturn = commandToReturn;
}

@Override
public HystrixMetricsPublisherCommand getMetricsPublisherForCommand(HystrixCommandKey commandKey, HystrixCommandGroupKey commandGroupKey, HystrixCommandMetrics metrics, HystrixCircuitBreaker circuitBreaker, HystrixCommandProperties properties) {
return commandToReturn;
}
}
}