
org.xson.tangyuan.executor.ServiceActuator Maven / Gradle / Ivy
package org.xson.tangyuan.executor;
import java.util.LinkedList;
import org.xson.common.object.XCO;
import org.xson.logging.Log;
import org.xson.logging.LogFactory;
import org.xson.tangyuan.TangYuanContainer;
import org.xson.tangyuan.aop.AopSupport;
import org.xson.tangyuan.aop.AspectVo.PointCut;
import org.xson.tangyuan.ognl.convert.ParameterConverter;
import org.xson.tangyuan.rpc.RpcProxy;
import org.xson.tangyuan.rpc.RpcServiceNode;
import org.xson.tangyuan.task.AsyncTask;
import org.xson.tangyuan.xml.node.AbstractServiceNode;
public class ServiceActuator {
private static Log log = LogFactory.getLog(ServiceActuator.class);
private static ThreadLocal contextThreadLocal = new ThreadLocal();
private static ParameterConverter converter = new ParameterConverter();
private static AopSupport aop = null;
private static volatile boolean running = true;
private static boolean onlyProxy = false;
/** 线程中的上下文 */
static class ThreadServiceContext {
/** 单个上下文 */
private ServiceContext context;
/** 单个上队列 */
private LinkedList contextQueue;
/**
* 获取或者创建新的上下文
*
* @param isNew
* 是否创建新的上下文
*/
public ServiceContext getOrCreate(boolean isNew) {
// 最初
if (null == context && null == contextQueue) {
context = new ServiceContext();
log.debug("open a new context. hashCode[" + context.hashCode() + "]");
return context;
}
ServiceContext returnContext = null;
// 之后的情况
if (isNew) {
if (null != context && null == contextQueue) {
contextQueue = new LinkedList();
contextQueue.push(context);
context = null;
ServiceContext newContext = new ServiceContext();
log.debug("open a new context. hashCode[" + newContext.hashCode() + "] in new");
contextQueue.push(newContext);
returnContext = newContext;
} else if (null == context && null != contextQueue) {
ServiceContext newContext = new ServiceContext();
log.debug("open a new context. hashCode[" + newContext.hashCode() + "] in new");
contextQueue.push(newContext);
returnContext = newContext;
} else {
throw new ServiceException("Wrong context and contextQueue in new");
}
} else {
if (null != this.context) {
returnContext = this.context;
} else if (null != this.contextQueue) {
returnContext = this.contextQueue.peek();
} else {
throw new ServiceException("Wrong context and contextQueue");
}
log.debug("follow an existing context. hashCode[" + returnContext.hashCode() + "], context[" + (returnContext.counter + 1) + "]");
returnContext.counter++;
}
return returnContext;
}
/** 仅仅获取上下文 */
public ServiceContext get() {
if (null != this.context) {
return this.context;
} else if (null != this.contextQueue) {
return this.contextQueue.peek();
} else {
return null;
}
}
/**
* 回收上下文
*
* @return true: 代表线程中需要删除
*/
public boolean recycle() {
if (null != this.context) {
this.context = null;
return true;
} else if (null != this.contextQueue) {
this.contextQueue.pop();
if (this.contextQueue.isEmpty()) {
return true;
}
}
return false;
}
}
@SuppressWarnings("static-access")
public static void shutdown() {
running = false;
long start = System.currentTimeMillis();
long maxWaitTimeForShutDown = TangYuanContainer.getInstance().getMaxWaitTimeForShutDown();
while (ServiceContext.globleCounter.get() > 0) {
if ((System.currentTimeMillis() - start) > maxWaitTimeForShutDown) {
log.error("wait for service to close timeout, The current context number " + ServiceContext.globleCounter.get());
return;
}
log.info("waiting for service to close.");
try {
Thread.currentThread().sleep(500L);
} catch (InterruptedException e) {
log.error("wait for service to close exception", e);
return;
}
}
log.info("service has been closed normally.");
}
public static void openOnlyProxyMode() {
onlyProxy = true;
}
public static void openAop() {
aop = AopSupport.getInstance();
}
/** 检查是否是还有存在的上下文中调用, 用于用户安全的关闭 */
private static void check() {
if (running) {
return;
}
boolean existingContext = (null == contextThreadLocal.get()) ? false : true;
if (!existingContext) {
throw new ServiceException("The current system is shutting down and no longer handles the new service.");
}
}
/** 方法之前的线程调用 */
private static ServiceContext begin(boolean isNew) {
ThreadServiceContext threadContext = contextThreadLocal.get();
if (null == threadContext) {
threadContext = new ThreadServiceContext();
contextThreadLocal.set(threadContext);
}
return threadContext.getOrCreate(isNew);
}
/** 无异常的结束 */
private static void endOnSuccess() {
ThreadServiceContext threadContext = contextThreadLocal.get();
if (null != threadContext) {
ServiceContext context = threadContext.get();
if (null == context) {
contextThreadLocal.remove();
return;
}
log.debug("context--. hashCode[" + context.hashCode() + "], context[" + (context.counter - 1) + "]");
if (--context.counter < 1) {
if (null == context.getExceptionInfo()) {
try {
context.finish();// 这里是确定的提交
} catch (Throwable e) {
context.finishOnException();
log.error("SqlService commit exception", e);
}
} else {
context.finishOnException();
}
log.debug("close a context. hashCode[" + context.hashCode() + "]");
context.stopMonitor();// stop monitor
if (threadContext.recycle()) {
contextThreadLocal.remove();
}
}
} else {
contextThreadLocal.remove();
}
}
/** 发生异常的结束 */
protected static void endOnException(Throwable throwable, AbstractServiceNode service) {
// 如果当前可以处理,当前处理; 如果当前不能处理,上抛,不做日志输出
ThreadServiceContext threadContext = contextThreadLocal.get();
ServiceContext context = threadContext.get();
if (--context.counter < 1) {
context.finishOnException();
log.error("Execute service exception: " + service.getServiceKey(), throwable);
log.debug("close a context. hashCode[" + context.hashCode() + "] on exception");
context.stopMonitor();
if (threadContext.recycle()) {
contextThreadLocal.remove();
}
// 最后一层抛出的异常
if (throwable instanceof ServiceException) {
throw (ServiceException) throwable;
}
throw new ServiceException("Execute service exception: " + service.getServiceKey(), throwable);
} else {
ServiceException ex = null;
try {
context.onException(service.getServiceType(), throwable, "Execute service exception: " + service.getServiceKey());
} catch (ServiceException e) {
ex = e;
}
if (null != ex) {
throw ex;
}
}
}
@SuppressWarnings("unchecked")
public static T execute(String serviceURI, Object arg) throws ServiceException {
check();// 检查系统是否已经正在关闭中了
log.info("actuator service: " + serviceURI);
if (onlyProxy) {
return (T) executeProxy(serviceURI, arg);
}
final AbstractServiceNode service = findService(serviceURI);
if (null == service) {
throw new ServiceException("Service does not exist: " + serviceURI);// 上抛异常
}
// Object data = converter.parameterConvert(arg, service.getResultType());
if (null != aop) {
aop.execBefore(service, arg, PointCut.BEFORE_CHECK);// 前置切面
aop.execBefore(service, arg, PointCut.BEFORE_ALONE);// 前置切面
}
// A. 获取上下文
ServiceContext context = begin(false);
// B.执行服务
context.updateMonitor(serviceURI);
Object result = null;
Throwable ex = null;
try {
if (null != aop) {
aop.execBefore(service, arg, PointCut.BEFORE_JOIN);// 前置切面
}
Object data = converter.parameterConvert(arg, service.getResultType());
service.execute(context, data);
result = service.getResult(context);// 只有类型转换时发生异常
if (null != aop) {
aop.execAfter(service, arg, result, ex, PointCut.AFTER_JOIN);
}
} catch (Throwable e) {
ex = e;
} finally {
// 新增后置处理
ServiceException throwEx = null;
try {
if (null != ex) {
endOnException(ex, service);
} else {
endOnSuccess();
}
} catch (ServiceException se) {
throwEx = se;
}
if (null != aop) {
aop.execAfter(service, arg, result, ex, PointCut.AFTER_ALONE);
}
if (null != throwEx) {
throw throwEx;
}
}
return (T) result;
}
/**
* 单独环境
*/
public static T executeAlone(String serviceURI, Object arg) throws ServiceException {
check();// 检查系统是否已经正在关闭中了
return executeAlone(serviceURI, arg, true);
}
@SuppressWarnings("unchecked")
public static T executeAlone(String serviceURI, Object arg, boolean throwException) throws ServiceException {
log.info("execute alone service: " + serviceURI);
if (onlyProxy) {
return (T) executeProxy(serviceURI, arg);
}
final AbstractServiceNode service = findService(serviceURI);
if (null == service) {
throw new ServiceException("Service does not exist: " + serviceURI);
}
if (null != aop) {
aop.execBefore(service, arg, PointCut.BEFORE_CHECK);// 前置切面
aop.execBefore(service, arg, PointCut.BEFORE_ALONE);// 前置切面
}
ServiceContext context = begin(true);
context.updateMonitor(serviceURI);// monitor
Object result = null;
Throwable ex = null;
try {
if (null != aop) {
aop.execBefore(service, arg, PointCut.BEFORE_JOIN);// 前置切面
}
Object data = converter.parameterConvert(arg, service.getResultType());
service.execute(context, data);
result = service.getResult(context);// 只有类型转换是发生异常
if (null != aop) {
aop.execAfter(service, arg, result, ex, PointCut.AFTER_JOIN);
}
} catch (Throwable e) {
ex = e;
} finally {
// 新增后置处理
ServiceException throwEx = null;
try {
if (null != ex) {
endOnException(ex, service);
} else {
endOnSuccess();
}
} catch (ServiceException se) {
throwEx = se;
}
if (null != aop) {
aop.execAfter(service, arg, result, ex, PointCut.AFTER_ALONE);
}
if (null != throwEx) {
if (throwException) {
throw throwEx;
} else {
log.error("Execute service exception: " + serviceURI, throwEx);
}
}
}
return (T) result;
}
/**
* 单独环境, 异步执行
*/
public static void executeAsync(final String serviceURI, final Object arg) {
check();
log.info("execute async service: " + serviceURI);
if (onlyProxy) {
TangYuanContainer.getInstance().addAsyncTask(new AsyncTask() {
@Override
public void run() {
executeProxy(serviceURI, arg);
}
});
return;
}
final AbstractServiceNode service = findService(serviceURI);
if (null == service) {
throw new ServiceException("Service does not exist: " + serviceURI);
}
if (null != aop) {
aop.execBefore(service, arg, PointCut.BEFORE_CHECK);// 前置切面
aop.execBefore(service, arg, PointCut.BEFORE_ALONE);// 前置切面
}
TangYuanContainer.getInstance().addAsyncTask(new AsyncTask() {
@Override
public void run() {
ServiceContext context = begin(false);// 这里是在新的线程中
context.updateMonitor(serviceURI);// monitor
Object result = null;
Throwable ex = null;
try {
if (null != aop) {
aop.execBefore(service, arg, PointCut.BEFORE_JOIN);// 前置切面
}
Object data = converter.parameterConvert(arg, service.getResultType());
service.execute(context, data);
result = service.getResult(context);
if (null != aop) {
aop.execAfter(service, arg, result, ex, PointCut.AFTER_JOIN);
}
// 这里是最终的提交
context.finish();
context.setResult(null);
} catch (Throwable e) {
ex = e;
// 这里是最终的回滚
context.finishOnException();
log.error("Execute service exception: " + serviceURI, e);
} finally {
context.stopMonitor();
contextThreadLocal.remove();
log.debug("close a context. hashCode[" + context.hashCode() + "]");
// 新增后置处理
if (null != aop) {
aop.execAfter(service, arg, result, ex, PointCut.AFTER_ALONE);
}
}
}
});
}
/**
* 获取服务
* a.b|www.xx.com/a/b
*/
private static AbstractServiceNode findService(String serviceURL) {
try {
// 查询本地服务
AbstractServiceNode service = TangYuanContainer.getInstance().getService(serviceURL);
if (null != service) {
return service;
}
// TODO serviceURL有可能是个不合法的URI,
// 查询远程服务
service = TangYuanContainer.getInstance().getDynamicService(serviceURL);
if (null != service) {
return service;
}
// 创建新的远程服务
return createDynamicService(serviceURL);
} catch (Throwable e) {
log.error("Invalid service url: " + serviceURL, e);
}
return null;
}
private static Object executeProxy(String serviceURI, Object arg) {
Object result = null;
try {
result = RpcProxy.call(serviceURI, (XCO) arg);
} catch (Throwable e) {
if (e instanceof ServiceException) {
throw (ServiceException) e;
} else {
throw new ServiceException(e);
}
}
return result;
}
private static AbstractServiceNode createDynamicService(String serviceURL) {
AbstractServiceNode service = null;
if (null == aop) {
service = new RpcServiceNode(serviceURL);
TangYuanContainer.getInstance().addDynamicService(service);
return service;
}
// 是否是拦截方
if (aop.isInterceptor(serviceURL)) {
service = new RpcServiceNode(serviceURL);
TangYuanContainer.getInstance().addDynamicService(service);
return service;
}
service = new RpcServiceNode(serviceURL);
// 检查并设置被拦截方
aop.checkAndsetIntercepted(serviceURL, service);
TangYuanContainer.getInstance().addDynamicService(service);
return service;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy