现在的位置: 首页 > 综合 > 正文

EDF

2013年08月13日 ⁄ 综合 ⁄ 共 7984字 ⁄ 字号 评论关闭
package czp.opensource.edf;

public class EDFEvent {

	/**
	 * 事件源
	 */
	private Object from;
	/**
	 * 异常
	 */
	private Throwable error;

	/**
	 * 事件的具体内容
	 */
	private Object body;
	
	/**
	 * 事件类型
	 */
	private EDFEventType type;
	
	
	public EDFEvent(Object from, Throwable error, Object body, EDFEventType type) {
		this.from = from;
		this.error = error;
		this.body = body;
		this.type = type;
	}
	
	public EDFEvent(Object body, EDFEventType type) {
		this.body = body;
		this.type = type;
	}

	public EDFEvent() {
	}

	/**
	 * 
	 * @return 事件的内容
	 */
	public Object getBody() {
		return body;
	}

	/**
	 * 
	 * @param body 事件的内容
	 */
	public void setBody(Object body) {
		this.body = body;
	}

	/**
	 * 
	 * @param from 事件的发送者
	 */
	public void setFrom(Object from) {
        this.from = from;		
	}

	/**
	 * 
	 * @param error 事件的异常
	 */
	public void setError(Throwable error) {
		this.error = error;
	}


	/**
	 * 
	 * @return 事件的发送者
	 */
	public Object getFrom() {
		return from;
	}

	/**
	 * 
	 * @return 事件异常
	 */
	public Throwable getError() {
		return error;
	}

	/**
	 * 
	 * @return 事件类型
	 */
	public EDFEventType getType() {
		return this.type;
	}

	/**
	 * 
	 * @param type 事件类型
	 */
	public void setType(EDFEventType type) {
		this.type = type;
	}

	@Override
	public String toString() {
		StringBuilder str = new StringBuilder();
		str.append("EDFEvent from:").append(from).append(",error:").append(error)
		.append(",type:").append(type).append(",body:").append(body);
		return str.toString();
	}
   
}
//---------

package czp.opensource.edf;

/**
 * 事件的处理器
 * 
 * @author CaoZhongping
 *
 */
public interface EDFEventHandler {

	/**
	 * 处理具体的事件
	 * @param event  容器分配的事件
	 * @return Object 返回值 
	 */
	Object handle(EDFEvent event);


	/**
	 * 处理异常事件
	 * @param event 容器分配的异常事件
	 */
	void handdleError(EDFEvent event);

	/**
	 * @return EDFEventType 关注的事件类型
	 */
	EDFEventType getMatchType();
}
//------

package czp.opensource.edf;

/**
 * 事件类型接口默认提供两个实现:
 * <pre>
 * 1 错误类型ERROR_TYPE,当处理事件发生
 *   异常时会发送该类型的事件并调用handle的handleError
 *   调用者一般不需要发送异常类型的事件
 * 2 所有类型ALL_TYPE,如果一个handle注册了ERROR_TYPE
 *   则表示该关注所有事件,因为isMatch恒返回true
 * 使用者需要实现  getType()和isMatch(),例如:
 * 
 *   public class SimpleEDFEventType implements EDFEventType {

		private String myType;
		
		public SimpleEDFEventType(String myType) {
			this.myType = myType;
		}
	
		@Override
		public String getType() {
			return myType;
		}
	
		@Override
		public boolean isMatch(EDFEventType type) {
			return type.getType().equalsIgnoreCase(getType());
		}

	}
 * 
 * </pre>
 * 
 * @author CaoZhongping
 *
 */
public interface EDFEventType {

	/**
	 * @return 事件类型的名称
	 */
	String getType();
	
	/**
	 * 反应器在处理事件时会调用
	 * 该方法找到该事件的handler
	 * 这个方法应该尽可能的简单
	 * 
	 * @param type 事件类型
	 * @return boolean 是否匹配
	 */
	boolean isMatch(EDFEventType type);
	
	/**
	 * 错误事件类型
	 */
	EDFEventType ERROR_TYPE = new EDFEventType(){

		private String type="EDFEventType_ERROR";
		
		@Override
		public String getType() {
			return type;
		}

		@Override
		public boolean isMatch(EDFEventType eventType) {
			return eventType.getType().equals(getType());
		}
		
	};
	/**
	 * 所有的事件类型isMatch恒为true
	 * 也就是关注所有的事件
	 */
	EDFEventType ALL_TYPE = new EDFEventType() {
		private String type="EDFEventType_ALL";
		@Override
		public boolean isMatch(EDFEventType type) {
			return true;
		}
		
		@Override
		public String getType() {
			return type;
		}
	};
}
//-----------

package czp.opensource.edf;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;


/**
 * 事件驱动框架的事件反应器
 * 
 * @author CaoZhongping
 *
 */
public class EDFReactor implements Runnable{

	/**
	 * 每个处理器默认的处理超时时间
	 */
	private static final long DEFAULT_TIME_OUT_SEC = 15;

	/**
	 * 默认的队列大小
	 */
	private final static int DEFAULT_QUEUE_CAPCITY = 50;
	/**
	 * 事件队列
	 */
	private BlockingQueue<EDFEvent> queue;
	
	/**
	 * 分派线程池
	 */
	private ExecutorService dispatchService;
	
	/**
	 * 工作线程池
	 */
	private ExecutorService workService;

	/**
	 * 队列容量
	 */
	private int eventQueueCapability;

	/**
	 * 事件处理器
	 */
	private Map<String, List<EDFEventHandler>> handlers;

	/**
	 * 创建反应器的线程
	 */
	private Thread createThread;
	
	private volatile boolean isStop;
	
	public EDFReactor(ExecutorService dispatchService,
			ExecutorService workService,int  eventQueueMaxSize) {
		this.dispatchService = dispatchService;
		this.workService = workService;
		this.queue = new ArrayBlockingQueue<EDFEvent>(eventQueueMaxSize);
		this.handlers = new ConcurrentHashMap<String, List<EDFEventHandler>>();
		this.createThread = Thread.currentThread();
	}

	public EDFReactor()
	{
		this(Executors.newSingleThreadExecutor(), Executors.newCachedThreadPool(), DEFAULT_QUEUE_CAPCITY);
	}
	/**
	 * 添加处理器
	 * @param eventHandler
	 */
	public void addEventHandler(EDFEventHandler eventHandler)
	{
		String type = eventHandler.getMatchType().getType();
		List<EDFEventHandler> ls = handlers.get(type);
		if(ls==null)
		{
			ls = new CopyOnWriteArrayList<EDFEventHandler>();
			ls.add(eventHandler);
			handlers.put(type, ls);
		}else{
			ls.add(eventHandler);
		}
	}
	/**
	 * 启动反应器
	 */
	public void start(){
		if(dispatchService.isShutdown())
		{
			throw new RuntimeException("the EDFReactor has Shutdown ,Please create a new EDFReactor");
		}
		this.dispatchService.execute(this);
		
	}

	/**
	 * 停止反应器
	 * 只有反应器的创建线程可以终止它
	 */
	public void stop()
	{
		if(Thread.currentThread().equals(createThread))
		{
			this.isStop = true;
			this.queue.clear();
			this.handlers.clear();
			this.dispatchService.shutdownNow();
			this.workService.shutdownNow();
		}else{
			throw new RuntimeException("EDFReactor stop() only be called by create thread");
		}
	}
	

    /**
     * @return 队列的容量
     */
	public int getEventQueueCapability() {
		return eventQueueCapability;
	}

	/**
	 *添加事件到队列
	 * @param event
	 */
	public void sendEvent(EDFEvent event)
	{
		this.queue.offer(event);
	}
	/**
	 * 分派线程开始
	 */
	@Override
	public void run() {
		while(!isStop)
		{
			try {
				EDFEvent ev = queue.take();
				handleEvent(ev);
			} catch (Exception e) {
				sendExceptionEvent(e);
			}
			
		}
	}

	/**
	 * 在工作线程里调用具体的事件处理器
	 * 
	 * @param ev
	 */
	private void handleEvent(EDFEvent ev) {
		List<EDFEventHandler> ls = handlers.get(ev.getType().getType());
		if(ls!=null)
		{
			for(EDFEventHandler hdl:ls)
			{
				Future<?> future = null;
				try {
					final EDFEventTask task = new EDFEventTask(ev,hdl);
					future = workService.submit(task);
					if(!future.isDone())
					{
						future.get(DEFAULT_TIME_OUT_SEC, TimeUnit.SECONDS);
					}
					
				}catch (Exception e) {
					sendExceptionEvent(e);
				}
			}
		}
	}

	/**
	 * 发送异常事件
	 * @param throwable
	 */
	public void sendExceptionEvent(Throwable throwable) {
		EDFEvent event = new EDFEvent();
		event.setFrom(this);
		event.setError(throwable);
		event.setType(EDFEventType.ERROR_TYPE);
		sendEvent(event);
	}
	/**
	 * 具体的事件
	 * 
	 * @author CaoZhongping
	 *
	 */
	private static  class EDFEventTask implements Callable<Object> {

		private EDFEvent event;
		private EDFEventHandler handle;

		public EDFEventTask(EDFEvent event, EDFEventHandler handle) {
			this.event = event;
			this.handle = handle;
			
		}

		@Override
		public Object call() throws Exception {
			if(event.getType().isMatch(EDFEventType.ERROR_TYPE))
			{
				handle.handdleError(event);
			}else if(handle.getMatchType().isMatch(event.getType()))
			{
				return handle.handle(event);
			}
			return null;
		}
	}
}
//---------

package czp.opensource.edf.demo;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import czp.opensource.edf.EDFEvent;
import czp.opensource.edf.EDFEventHandler;
import czp.opensource.edf.EDFEventType;
import czp.opensource.edf.EDFReactor;

/**
 * <pre>
 *   参见:czp.opensource.edf.demo.SimpleDemo
 * </pre>
 * @author CaoZhongping
 *
 */
public class SimpleDemo {

	public static void main(String[] args) throws InterruptedException {
		
		//创建一个反应器通常一个系统创建一个reactor
		final EDFReactor reactor = new EDFReactor();
		//添加一个处理器
		reactor.addEventHandler(new SimpleEDFEventHandle());
		//启动反应器
		reactor.start();
		
		final CountDownLatch sd = new CountDownLatch(1);
		ExecutorService service = Executors.newFixedThreadPool(5);
		
		service.execute(new Runnable() {
			
			@Override
			public void run() {
				int i = 0;
				while(i++<20)
				{
					try {
						//创建事件
						EDFEvent event = new EDFEvent();
						event.setType(new SimpleEDFEventType("test"));
						event.setFrom(this);
						//发送事件
						reactor.sendEvent(event );
						Thread.sleep(10);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				sd.countDown();
				
			}
		});
		sd.await();
		service.shutdownNow();
		//系统注销时stop反应器
		reactor.stop();
	}
}
/**
 * 简单的处理器
 * 
 * @author CaoZhongping
 *
 */
class SimpleEDFEventHandle implements EDFEventHandler {

	private EDFEventType myType = new SimpleEDFEventType("test");
	
	@Override
	public Object handle(EDFEvent event) {
		System.out.println("get msg "+event);
		return null;
	}

	@Override
	public void handdleError(EDFEvent event) {
     System.out.println(event.getError());
	}

	@Override
	public EDFEventType getMatchType() {
		return myType;
	}
    
}
/**
 * 简单的事件类型
 * 
 * @author CaoZhongping
 */
class SimpleEDFEventType implements EDFEventType {

	private String myType;
	
	public SimpleEDFEventType(String myType) {
		this.myType = myType;
	}

	@Override
	public String getType() {
		return myType;
	}

	@Override
	public boolean isMatch(EDFEventType type) {
		return type.getType().equalsIgnoreCase(getType());
	}

	@Override
	public String toString() {
		return "SimpleEDFEventType [myType=" + myType + "]";
	}
	
}

抱歉!评论已关闭.