/**
* Dianping.com Inc.
* Copyright (c) 2003-2013 All Rights Reserved.
*/
package com.dianping.pigeon.remoting.provider.util;
import java.util.List;
import com.dianping.pigeon.monitor.Monitor;
import com.dianping.pigeon.monitor.MonitorLoader;
import com.dianping.pigeon.monitor.MonitorTransaction;
import com.dianping.pigeon.remoting.common.domain.InvocationContext.TimePhase;
import com.dianping.pigeon.remoting.common.domain.InvocationContext.TimePoint;
import com.dianping.pigeon.remoting.common.domain.InvocationRequest;
import com.dianping.pigeon.remoting.common.domain.InvocationResponse;
import com.dianping.pigeon.remoting.common.monitor.SizeMonitor;
import com.dianping.pigeon.remoting.common.util.Constants;
import com.dianping.pigeon.remoting.provider.domain.ProviderChannel;
import com.dianping.pigeon.remoting.provider.domain.ProviderContext;
import com.dianping.pigeon.remoting.provider.process.ProviderInterceptor;
import com.dianping.pigeon.remoting.provider.process.ProviderInterceptorFactory;
import com.dianping.pigeon.remoting.provider.process.ProviderProcessInterceptor;
import com.dianping.pigeon.remoting.provider.process.ProviderProcessInterceptorFactory;
import com.dianping.pigeon.remoting.provider.process.statistics.ProviderStatisticsHolder;
public final class ProviderHelper {
private static final Monitor monitor = MonitorLoader.getMonitor();
private static ThreadLocal<Boolean> isStartAsync = new ThreadLocal<Boolean>();
private static ThreadLocal<ProviderContext> tlContext = new ThreadLocal<ProviderContext>();
public static void setContext(ProviderContext context) {
tlContext.set(context);
}
public static ProviderContext getContext() {
ProviderContext context = tlContext.get();
tlContext.remove();
return context;
}
public static void clearContext() {
tlContext.remove();
}
public static ProviderContext startAsync() {
ProviderContext providerContext = getContext();
if (providerContext != null) {
providerContext.setAsync(true);
}
return providerContext;
}
public static void writeSuccessResponse(ProviderContext context, Object returnObj) {
if (context == null) {
return;
}
InvocationRequest request = context.getRequest();
InvocationResponse response = null;
if ((Constants.REPLY_MANUAL || context.isAsync()) && request.getCallType() != Constants.CALLTYPE_NOREPLY) {
response = ProviderUtils.createSuccessResponse(request, returnObj);
context.getTimeline().add(new TimePoint(TimePhase.B, System.currentTimeMillis()));
ProviderChannel channel = context.getChannel();
MonitorTransaction transaction = null;
if (Constants.MONITOR_ENABLE) {
MonitorTransaction currentTransaction = monitor.getCurrentServiceTransaction();
try {
if (currentTransaction == null) {
transaction = monitor.createTransaction("PigeonServiceCallback", context.getMethodUri(),
context);
if (transaction != null) {
transaction.setStatusOk();
monitor.logEvent("PigeonService.app", request.getApp(), "");
transaction.addData("CallType", request.getCallType());
String reqSize = SizeMonitor.getInstance().getLogSize(request.getSize());
if (reqSize != null) {
monitor.logEvent("PigeonService.requestSize", reqSize, "" + request.getSize());
}
}
}
} catch (Throwable e) {
monitor.logMonitorError(e);
}
try {
channel.write(context, response);
} finally {
if (Constants.MONITOR_ENABLE) {
if (response != null && response.getSize() > 0) {
String respSize = SizeMonitor.getInstance().getLogSize(response.getSize());
if (respSize != null) {
monitor.logEvent("PigeonService.responseSize", respSize, "" + response.getSize());
}
}
if (transaction != null) {
context.getTimeline().add(new TimePoint(TimePhase.E, System.currentTimeMillis()));
try {
transaction.complete();
} catch (Throwable e) {
monitor.logMonitorError(e);
}
}
}
}
}
}
ProviderStatisticsHolder.flowOut(request);
List<ProviderProcessInterceptor> interceptors = ProviderProcessInterceptorFactory.getInterceptors();
for (ProviderProcessInterceptor interceptor : interceptors) {
interceptor.postInvoke(request, response);
}
List<ProviderInterceptor> contextInterceptors = ProviderInterceptorFactory.getInterceptors();
for (ProviderInterceptor interceptor : contextInterceptors) {
interceptor.postInvoke(context);
}
}
public static void writeFailureResponse(ProviderContext context, Throwable exeption) {
if (context == null) {
return;
}
if (Constants.REPLY_MANUAL || context.isAsync()) {
InvocationRequest request = context.getRequest();
InvocationResponse response = ProviderUtils.createServiceExceptionResponse(request, exeption);
ProviderChannel channel = context.getChannel();
channel.write(context, response);
ProviderStatisticsHolder.flowOut(request);
List<ProviderProcessInterceptor> interceptors = ProviderProcessInterceptorFactory.getInterceptors();
for (ProviderProcessInterceptor interceptor : interceptors) {
interceptor.postInvoke(request, response);
}
List<ProviderInterceptor> contextInterceptors = ProviderInterceptorFactory.getInterceptors();
for (ProviderInterceptor interceptor : contextInterceptors) {
interceptor.postInvoke(context);
}
}
}
}