/**
*
*/
package com.taobao.top.analysis.node.component;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.zookeeper.ZooKeeper;
import com.taobao.top.analysis.config.IConfig;
import com.taobao.top.analysis.exception.AnalysisException;
import com.taobao.top.analysis.node.INode;
import com.taobao.top.analysis.node.event.INodeEvent;
/**
* 抽象节点处理主骨骼结构,当前节点循环执行某一些逻辑,后台也支持监听事件发生
* @author fangweng
* @Email fangweng@taobao.com
* 2011-11-28
*
*/
public abstract class AbstractNode<E extends INodeEvent,C extends IConfig> implements INode<E,C>{
private static final Log logger = LogFactory.getLog(AbstractNode.class);
protected C config;
/**
* 消息队列
*/
private BlockingQueue<E> queue;
/**
* 后台监控者,来接受事件,处理外部消息
*/
private Inspector inspector;
/**
* 节点内部线程,处理节点内部周期工作
*/
private Thread innerThread;
/**
* 用于暂停节点运作的锁
*/
private Semaphore pauseSemaphore;
ZooKeeper zk = null;
/**
* 节点启动的时间
*/
protected long nodeStartTimeStamp;
public AbstractNode()
{
queue = new LinkedBlockingQueue<E>();
pauseSemaphore = new Semaphore(1);
inspector = new Inspector();
inspector.start();
}
public void suspendNode()
{
try
{
pauseSemaphore.acquire();
logger.warn("Node be suspend!");
}
catch(Exception ex)
{
logger.error("suspendNode error!",ex);
}
}
public void awaitNode()
{
try
{
pauseSemaphore.release();
logger.warn("Node be await!");
}
catch(Exception ex)
{
logger.error("awaitNode error!",ex);
}
}
/**
* 启动节点
*/
@Override
public void startNode()
{
innerThread = new Thread(this);
innerThread.start();
logger.info("trying to start node");
nodeStartTimeStamp = System.currentTimeMillis();
}
/**
* 停止节点
*/
@Override
public void stopNode()
{
innerThread.interrupt();
inspector.interrupt();
}
public C getConfig() {
return config;
}
public void setConfig(C config) {
this.config = config;
}
@Override
public void run() {
try
{
this.init();
while(!Thread.currentThread().isInterrupted())
{
try
{
pauseSemaphore.acquire();
process();
}
catch(InterruptedException e)
{
logger.error(e,e);
Thread.currentThread().interrupt();
}
catch(AnalysisException e)
{
logger.error(e,e);
}
finally
{
pauseSemaphore.release();
}
}
}
catch(Throwable ex)
{
logger.error(ex,ex);
System.exit(-1);
}
finally
{
this.inspector.interrupt();
this.releaseResource();
logger.info("Node stopped ...");
}
}
@Override
public boolean addEvent(E event)
{
return queue.offer(event);
}
private class Inspector extends Thread
{
@Override
public void run() {
while(!Thread.currentThread().isInterrupted())
{
try
{
E event = queue.poll(1000, TimeUnit.MILLISECONDS);
//事件处理是单线程
if (event != null)
{
processEvent(event);
}
}
catch(InterruptedException e)
{
//do nothing
logger.error(e);
Thread.currentThread().interrupt();
}
catch(Throwable e)
{
logger.error(e,e);
}
}
logger.warn("Node Inspector stop now.");
}
}
}