package com.dianping.pigeon.remoting.provider.process.statistics;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.dianping.pigeon.log.Logger;
import com.dianping.pigeon.config.ConfigManagerLoader;
import com.dianping.pigeon.log.LoggerLoader;
import com.dianping.pigeon.remoting.common.domain.InvocationRequest;
import com.dianping.pigeon.remoting.common.util.Constants;
public final class ProviderStatisticsHolder {
private static final Logger logger = LoggerLoader.getLogger(ProviderStatisticsHolder.class);
private static ConcurrentHashMap<String, ProviderCapacityBucket> appCapacityBuckets = new ConcurrentHashMap<String, ProviderCapacityBucket>();
private static ConcurrentHashMap<String, ProviderCapacityBucket> methodCapacityBuckets = new ConcurrentHashMap<String, ProviderCapacityBucket>();
private static ConcurrentHashMap<String, ConcurrentHashMap<String, ProviderCapacityBucket>>
methodAppCapacityBuckets = new ConcurrentHashMap<>();
private static final ProviderCapacityBucket globalCapacityBucket = new ProviderCapacityBucket(null);
public static final boolean statEnable = ConfigManagerLoader.getConfigManager().getBooleanValue(
"pigeon.providerstat.enable", true);
public static void init() {
}
public static Map<String, ProviderCapacityBucket> getCapacityBuckets() {
return appCapacityBuckets;
}
public static ConcurrentHashMap<String, ProviderCapacityBucket> getMethodCapacityBuckets() {
return methodCapacityBuckets;
}
public static ConcurrentHashMap<String, ConcurrentHashMap<String, ProviderCapacityBucket>> getMethodAppCapacityBuckets() {
return methodAppCapacityBuckets;
}
public static ProviderCapacityBucket getMethodAppCapacityBucket(InvocationRequest request) {
final String requestMethod = request.getServiceName() + "#" + request.getMethodName();
ConcurrentHashMap<String, ProviderCapacityBucket> appBarrelMap = methodAppCapacityBuckets.get(requestMethod);
if (appBarrelMap == null) {
ConcurrentHashMap<String, ProviderCapacityBucket> newAppBarrelMap = new ConcurrentHashMap<>();
appBarrelMap = methodAppCapacityBuckets.putIfAbsent(requestMethod, newAppBarrelMap);
if (appBarrelMap == null) {
appBarrelMap = newAppBarrelMap;
}
}
String fromApp = request.getApp();
if (fromApp == null) {
fromApp = "";
}
ProviderCapacityBucket barrel = appBarrelMap.get(fromApp);
if (barrel == null) {
ProviderCapacityBucket newBarrel = new ProviderCapacityBucket(fromApp);
barrel = appBarrelMap.putIfAbsent(fromApp, newBarrel);
if (barrel == null) {
barrel = newBarrel;
}
}
return barrel;
}
public static ProviderCapacityBucket getCapacityBucket(InvocationRequest request) {
String fromApp = request.getApp();
if (fromApp == null) {
fromApp = "";
}
ProviderCapacityBucket barrel = appCapacityBuckets.get(fromApp);
if (barrel == null) {
ProviderCapacityBucket newBarrel = new ProviderCapacityBucket(fromApp);
barrel = appCapacityBuckets.putIfAbsent(fromApp, newBarrel);
if (barrel == null) {
barrel = newBarrel;
}
}
return barrel;
}
public static ProviderCapacityBucket getCapacityBucket(String requestMethod) {
ProviderCapacityBucket barrel = methodCapacityBuckets.get(requestMethod);
if (barrel == null) {
ProviderCapacityBucket newBarrel = new ProviderCapacityBucket(requestMethod);
barrel = methodCapacityBuckets.putIfAbsent(requestMethod, newBarrel);
if (barrel == null) {
barrel = newBarrel;
}
}
return barrel;
}
public static void flowIn(InvocationRequest request) {
if (checkRequestNeedStat(request)) {
// app level
ProviderCapacityBucket barrel = getCapacityBucket(request);
if (barrel != null) {
barrel.flowIn(request);
}
// method level
final String requestMethod = request.getServiceName() + "#" + request.getMethodName();
ProviderCapacityBucket methodBarrel = getCapacityBucket(requestMethod);
if (methodBarrel != null) {
methodBarrel.flowIn(request);
}
// method app level
ProviderCapacityBucket methodAppBarrel = getMethodAppCapacityBucket(request);
if (methodAppBarrel != null) {
methodAppBarrel.flowIn(request);
}
// global level
globalCapacityBucket.flowIn(request);
}
}
public static void flowOut(InvocationRequest request) {
if (checkRequestNeedStat(request)) {
// app level
ProviderCapacityBucket barrel = getCapacityBucket(request);
if (barrel != null) {
barrel.flowOut(request);
}
// method level
final String requestMethod = request.getServiceName() + "#" + request.getMethodName();
ProviderCapacityBucket methodBarrel = getCapacityBucket(requestMethod);
if (methodBarrel != null) {
methodBarrel.flowOut(request);
}
// method app level
ProviderCapacityBucket methodAppBarrel = getMethodAppCapacityBucket(request);
if (methodAppBarrel != null) {
methodAppBarrel.flowOut(request);
}
// global level
globalCapacityBucket.flowOut(request);
}
}
public static ProviderCapacityBucket getGlobalCapacityBucket() {
return globalCapacityBucket;
}
public static boolean checkRequestNeedStat(InvocationRequest request) {
if (request == null || request.getMessageType() != Constants.MESSAGE_TYPE_SERVICE) {
return false;
}
return statEnable;
}
public static void removeCapacityBucket(String fromApp) {
appCapacityBuckets.remove(fromApp);
}
}