NC57 定时任务TaskExecutor 控制单个任务

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sir_jun/article/details/37968695
/*
 * @(#)TaskExecutor.java 1.0 2004-10-12
 *
 * Copyright 2005 UFIDA Software Co. Ltd. All rights reserved.
 * UFIDA PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package nc.bs.uap.scheduler.impl;

import nc.bs.framework.common.IAttributeManager;
import nc.bs.framework.common.NCLocator;
import nc.bs.framework.component.RemoteProcessComponetFactory;
import nc.bs.framework.execute.Executor;
import nc.bs.framework.task.ICRController;
import nc.bs.framework.tx.NoSpecified;
import nc.bs.logging.Logger;
import nc.bs.uap.scheduler.ITask;
import nc.bs.uap.scheduler.Messages;
import nc.itf.uap.scheduler.IExecutorService;
import nc.vo.uap.scheduler.TaskStatus;
import nc.vo.uap.scheduler.TaskWrapper;

/**
 * 任务的执行器。对经过调度的任务进行处理和执行。由任务执行器池生成。
 * <p>
 * 在接到任务后首先开始执行任务,执行完毕后,把自己加入到任务执行器池的空闲线程队列;自身进入等待状态,等待任务执行器池唤醒。
 * 如果没有任务,则进入IDLE的等待状态,如果超时还没有分配的任务,则将通知任务执行器池。任务执行器池根据设定的规则处理此任务执行器。
 * 
 * @author yanglei
 * @author hgy 5.3
 * @since 3.0
 */
public class TaskExecutor extends Executor {

	private volatile TaskWrapper taskWrapper = null;

	/* 任务执行器所归属的线程池 */
	private TaskExecutorPool pool = null;

	private RemoteProcessComponetFactory factory;

	private IAttributeManager requestAttrMgr;

	private final ICRController crController;

	private static boolean SCHEDULE_TEST = "test".equals(System
			.getProperty("nc.scheduler.mode"));

	/**
	 * 构造任务执行器
	 * 
	 * @param name
	 *            任务执行器的名称。
	 * @param pool
	 *            任务执行器所归属的线程池。
	 */
	TaskExecutor(String name, TaskExecutorPool pool) {
		super(name);
		this.pool = pool;
		crController = NCLocator.getInstance().lookup(ICRController.class);
	}

	/**
	 * 执行器运行的主过程。
	 */
	@Override
	public void run() {
		for (;;) {
			manageNullTask();
			if (getTaskWrapper() == null) {
				if (pool.notifyTimeOut(this))
					return;
				else {
					continue;
				}
			} else {
				try {
					executeTask();
				} finally {
					TaskWrapper tw = getTaskWrapper();
					setTaskWrapper(null);
					if (pool.notifyFree(this, tw))
						return;

				}
			}
		}
	}

	/**
	 * 执行任务。
	 */
	private void executeTask() {
		boolean hasException = false;
		TaskWrapper tw = getTaskWrapper();
		// Add By 门志永@云达/新华书店项目2013-4-21 START 执行特定的后台任务
		/**
		 * XHFX物流接口_分书同步
		 * XHFX物流接口_运单同步
		 */
		if(tw.getTask().getType().equals("1")&&!tw.getTask().getName().equals("XHFX物流接口_运单333同步"))//同步BD_INVBASDOC_PKINVTEMP品种到中间库
			return;
		tw.setStatus(TaskStatus.RUNNING);
		logBeginExecute(tw);
		ITask task = tw.getTask();
		try {
			Logger.init(Messages.LOGGER_ID);
			long now = System.currentTimeMillis();
			TaskWrapper.taskWrapperContext.set(tw);
			bgProcess(tw, true, null);
			tw.setThread(Thread.currentThread());
			if (SCHEDULE_TEST
					|| task.getTaskBody().getClass().getAnnotation(
							NoSpecified.class) != null) {
				Messages.log.debug("execute task without default transaction: " + task.getTaskBody());
				task.getTaskBody().execute();
			} else {
				IExecutorService es = (IExecutorService) NCLocator
						.getInstance().lookup(IExecutorService.class.getName());
				es.executeTask_RequiresNew(task.getTaskBody());
			}
			tw.setStatus(TaskStatus.FINISHED);
			logExecuteFinished(tw, System.currentTimeMillis() - now);
		} catch (Exception e) {
			tw.setStatus(TaskStatus.FAILED);
			executeTaskException(tw, e);
			hasException = true;
		} finally {
			executeTaskFinally(hasException, tw);
			tw.setThread(null);
			if (tw.getCRToken() != null) {
				crController.releaseToken(tw.getCRToken());
				tw.setCRToken(null);
			}

			TaskWrapper.taskWrapperContext.set(null);
			Logger.reset();
		}
	}

	/**
	 * 执行时发生异常。
	 * 
	 * @param task
	 * @param e
	 */
	private void executeTaskException(TaskWrapper tw, Exception e) {
		if (e != null) {
			logExecuteTaskException(tw, e);
		} else {
			try {
				tw.getTask().getTaskBody().cancelExecute();
			} catch (Exception ex) {
				logException(ex);
			}
		}

		bgProcess(tw, false, e);
	}

	/**
	 * 任务执行完毕,将该任务的对象引用设置为<tt>null</tt>,并且通知由执行器池来处理该执行器。
	 * 
	 * @return
	 */
	private void executeTaskFinally(boolean hasException, TaskWrapper tw) {
		if (!hasException) {
			bgProcess(tw, false, null);
		}

		RemoteProcessComponetFactory factory = getRemoteProcessComponetFactory();
		if (factory != null) {
			factory.clearThreadScopePostProcess();
		}

		try {
			IAttributeManager requestAttrMgr = getAttributeManager();
			if (requestAttrMgr != null) {
				requestAttrMgr.clear();
			}
		} catch (Throwable thr) {
			Messages.log.error("Background executeTaskFinally error", thr);
		}
	}

	/**
	 * 如果该任务为<tt>null</tt>,则只等待一个超时时间。
	 */
	private void manageNullTask() {
		synchronized (this) {
			if (getTaskWrapper() == null) {
				try {
					wait(pool.getExecutorIdleTimeOut());
				} catch (InterruptedException e) {
					logException(e);
				}
			}
		}
	}

	/**
	 * 将任务传给任务执行器,并唤醒之(由线程池调用)。
	 * 
	 * @param taskWrapper
	 *            任务包装类,包括任务ID,任务对象,任务优先级
	 */
	synchronized void execute(TaskWrapper taskWrapper) {
		setTaskWrapper(taskWrapper);
		notifyAll();
	}

	public TaskWrapper getTaskWrapper() {
		return taskWrapper;
	}

	private void setTaskWrapper(TaskWrapper taskWrapper) {
		this.taskWrapper = taskWrapper;
	}

	private void logBeginExecute(TaskWrapper tw) {
		Messages.log.debug("Begin " + tw);
	}

	/**
	 * 对任务的执行产生的异常进行记录。
	 * 
	 * @param task
	 * @param e
	 */
	private void logExecuteTaskException(TaskWrapper tw, Exception e) {
		Messages.log.error("Error execute " + tw, e);

	}

	/**
	 * 对异常进行记录。
	 * 
	 * @param e
	 */
	private void logException(Throwable e) {
		Messages.log.warn(Messages.getString("TaskExecutor.exception"), e);
	}

	/**
	 * 对任务执行完毕进行记录。
	 * 
	 * @param e
	 */
	private void logExecuteFinished(TaskWrapper tw, long time) {
		Messages.log.debug("Finished " + tw + " spend time: " + time);
	}

	private RemoteProcessComponetFactory getRemoteProcessComponetFactory() {
		if (factory == null) {
			try {
				factory = (RemoteProcessComponetFactory) NCLocator
						.getInstance().lookup("RemoteProcessComponetFactory");
			} catch (Throwable thr) {
				Logger.error("Maybe the BizServer has not been started", thr);
			}
		}
		return factory;
	}

	private IAttributeManager getAttributeManager() {
		if (requestAttrMgr == null) {
			try {
				requestAttrMgr = (IAttributeManager) NCLocator
						.getInstance()
						.lookup(
								"nc.bs.framework.core.service.RequestAttributeManager");
			} catch (Throwable thr) {
				Logger.error("Maybe the BizServer has not been started", thr);
			}
		}
		return requestAttrMgr;
	}

	private void bgProcess(TaskWrapper tw, boolean pre, Throwable t) {
		try {
			RemoteProcessComponetFactory factory = getRemoteProcessComponetFactory();
			if (factory != null) {
				if (pre) {
					factory.preProcess();
				} else {
					if (t == null) {
						factory.postProcess();
					} else {
						factory.postErrorProcess(t);
					}
				}
			}
		} catch (Throwable thr) {
			Messages.log.error("Background process error", thr);
		}
	}

}

猜你喜欢

转载自blog.csdn.net/sir_jun/article/details/37968695