Copyright 2012 Netflix, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
/** * Copyright 2012 Netflix, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
package com.netflix.hystrix.strategy.metrics; import java.util.concurrent.ConcurrentHashMap; import com.netflix.hystrix.HystrixCircuitBreaker; import com.netflix.hystrix.HystrixCollapser; import com.netflix.hystrix.HystrixCollapserKey; import com.netflix.hystrix.HystrixCollapserMetrics; import com.netflix.hystrix.HystrixCollapserProperties; import com.netflix.hystrix.HystrixCommand; import com.netflix.hystrix.HystrixCommandGroupKey; import com.netflix.hystrix.HystrixCommandKey; import com.netflix.hystrix.HystrixCommandMetrics; import com.netflix.hystrix.HystrixCommandProperties; import com.netflix.hystrix.HystrixThreadPool; import com.netflix.hystrix.HystrixThreadPoolKey; import com.netflix.hystrix.HystrixThreadPoolMetrics; import com.netflix.hystrix.HystrixThreadPoolProperties; import com.netflix.hystrix.strategy.HystrixPlugins;
Factory for retrieving metrics publisher implementations.

This uses given HystrixMetricsPublisher implementations to construct publisher instances and caches each instance according to the cache key provided.

@ExcludeFromJavadoc
/** * Factory for retrieving metrics publisher implementations. * <p> * This uses given {@link HystrixMetricsPublisher} implementations to construct publisher instances and caches each instance according to the cache key provided. * * @ExcludeFromJavadoc */
public class HystrixMetricsPublisherFactory {
The SINGLETON instance for real use.

Unit tests will create instance methods for testing and injecting different publishers.

/** * The SINGLETON instance for real use. * <p> * Unit tests will create instance methods for testing and injecting different publishers. */
private static HystrixMetricsPublisherFactory SINGLETON = new HystrixMetricsPublisherFactory();
Get an instance of HystrixMetricsPublisherThreadPool with the given factory HystrixMetricsPublisher implementation for each HystrixThreadPool instance.
Params:
Returns:HystrixMetricsPublisherThreadPool instance
/** * Get an instance of {@link HystrixMetricsPublisherThreadPool} with the given factory {@link HystrixMetricsPublisher} implementation for each {@link HystrixThreadPool} instance. * * @param threadPoolKey * Pass-thru to {@link HystrixMetricsPublisher#getMetricsPublisherForThreadPool} implementation * @param metrics * Pass-thru to {@link HystrixMetricsPublisher#getMetricsPublisherForThreadPool} implementation * @param properties * Pass-thru to {@link HystrixMetricsPublisher#getMetricsPublisherForThreadPool} implementation * @return {@link HystrixMetricsPublisherThreadPool} instance */
public static HystrixMetricsPublisherThreadPool createOrRetrievePublisherForThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolMetrics metrics, HystrixThreadPoolProperties properties) { return SINGLETON.getPublisherForThreadPool(threadPoolKey, metrics, properties); }
Get an instance of HystrixMetricsPublisherCommand with the given factory HystrixMetricsPublisher implementation for each HystrixCommand instance.
Params:
Returns:HystrixMetricsPublisherCommand instance
/** * Get an instance of {@link HystrixMetricsPublisherCommand} with the given factory {@link HystrixMetricsPublisher} implementation for each {@link HystrixCommand} instance. * * @param commandKey * Pass-thru to {@link HystrixMetricsPublisher#getMetricsPublisherForCommand} implementation * @param commandOwner * Pass-thru to {@link HystrixMetricsPublisher#getMetricsPublisherForCommand} implementation * @param metrics * Pass-thru to {@link HystrixMetricsPublisher#getMetricsPublisherForCommand} implementation * @param circuitBreaker * Pass-thru to {@link HystrixMetricsPublisher#getMetricsPublisherForCommand} implementation * @param properties * Pass-thru to {@link HystrixMetricsPublisher#getMetricsPublisherForCommand} implementation * @return {@link HystrixMetricsPublisherCommand} instance */
public static HystrixMetricsPublisherCommand createOrRetrievePublisherForCommand(HystrixCommandKey commandKey, HystrixCommandGroupKey commandOwner, HystrixCommandMetrics metrics, HystrixCircuitBreaker circuitBreaker, HystrixCommandProperties properties) { return SINGLETON.getPublisherForCommand(commandKey, commandOwner, metrics, circuitBreaker, properties); }
Resets the SINGLETON object. Clears all state from publishers. If new requests come in instances will be recreated.
/** * Resets the SINGLETON object. * Clears all state from publishers. If new requests come in instances will be recreated. * */
public static void reset() { SINGLETON = new HystrixMetricsPublisherFactory(); SINGLETON.commandPublishers.clear(); SINGLETON.threadPoolPublishers.clear(); SINGLETON.collapserPublishers.clear(); } /* 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>(); /* package */ HystrixMetricsPublisherCommand getPublisherForCommand(HystrixCommandKey commandKey, HystrixCommandGroupKey commandOwner, HystrixCommandMetrics metrics, HystrixCircuitBreaker circuitBreaker, HystrixCommandProperties properties) { // attempt to retrieve from cache first HystrixMetricsPublisherCommand publisher = commandPublishers.get(commandKey.name()); if (publisher != null) { return publisher; } else { synchronized (this) { HystrixMetricsPublisherCommand existingPublisher = commandPublishers.get(commandKey.name()); if (existingPublisher != null) { return existingPublisher; } else { HystrixMetricsPublisherCommand newPublisher = HystrixPlugins.getInstance().getMetricsPublisher().getMetricsPublisherForCommand(commandKey, commandOwner, metrics, circuitBreaker, properties); commandPublishers.putIfAbsent(commandKey.name(), newPublisher); newPublisher.initialize(); return newPublisher; } } } } // String is ThreadPoolKey.name() (we can't use ThreadPoolKey directly as we can't guarantee it implements hashcode/equals correctly) private final ConcurrentHashMap<String, HystrixMetricsPublisherThreadPool> threadPoolPublishers = new ConcurrentHashMap<String, HystrixMetricsPublisherThreadPool>(); /* package */ HystrixMetricsPublisherThreadPool getPublisherForThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolMetrics metrics, HystrixThreadPoolProperties properties) { // attempt to retrieve from cache first HystrixMetricsPublisherThreadPool publisher = threadPoolPublishers.get(threadPoolKey.name()); if (publisher != null) { return publisher; } // it doesn't exist so we need to create it 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) { // we won the thread-race to store the instance we created so initialize it publisher.initialize(); // done registering, return instance that got cached return publisher; } else { // we lost so return 'existing' and let the one we created be garbage collected // without calling initialize() on it return existing; } }
Get an instance of HystrixMetricsPublisherCollapser with the given factory HystrixMetricsPublisher implementation for each HystrixCollapser instance.
Params:
Returns:HystrixMetricsPublisherCollapser instance
/** * Get an instance of {@link HystrixMetricsPublisherCollapser} with the given factory {@link HystrixMetricsPublisher} implementation for each {@link HystrixCollapser} instance. * * @param collapserKey * Pass-thru to {@link HystrixMetricsPublisher#getMetricsPublisherForCollapser} implementation * @param metrics * Pass-thru to {@link HystrixMetricsPublisher#getMetricsPublisherForCollapser} implementation * @param properties * Pass-thru to {@link HystrixMetricsPublisher#getMetricsPublisherForCollapser} implementation * @return {@link HystrixMetricsPublisherCollapser} instance */
public static HystrixMetricsPublisherCollapser createOrRetrievePublisherForCollapser(HystrixCollapserKey collapserKey, HystrixCollapserMetrics metrics, HystrixCollapserProperties properties) { return SINGLETON.getPublisherForCollapser(collapserKey, metrics, properties); } // String is CollapserKey.name() (we can't use CollapserKey directly as we can't guarantee it implements hashcode/equals correctly) private final ConcurrentHashMap<String, HystrixMetricsPublisherCollapser> collapserPublishers = new ConcurrentHashMap<String, HystrixMetricsPublisherCollapser>(); /* package */ HystrixMetricsPublisherCollapser getPublisherForCollapser(HystrixCollapserKey collapserKey, HystrixCollapserMetrics metrics, HystrixCollapserProperties properties) { // attempt to retrieve from cache first HystrixMetricsPublisherCollapser publisher = collapserPublishers.get(collapserKey.name()); if (publisher != null) { return publisher; } // it doesn't exist so we need to create it publisher = HystrixPlugins.getInstance().getMetricsPublisher().getMetricsPublisherForCollapser(collapserKey, metrics, properties); // attempt to store it (race other threads) HystrixMetricsPublisherCollapser existing = collapserPublishers.putIfAbsent(collapserKey.name(), publisher); if (existing == null) { // we won the thread-race to store the instance we created so initialize it publisher.initialize(); // done registering, return instance that got cached return publisher; } else { // we lost so return 'existing' and let the one we created be garbage collected // without calling initialize() on it return existing; } } }