package com.mogujie.tt.packet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import com.mogujie.tt.log.Logger;
import com.mogujie.tt.packet.action.Action;
import com.mogujie.tt.packet.action.ActionCallback;
/**
* Waiting list扫描线程, 一般情况下,这个线程只应该开启一条
*
* @author dolphinWang
* @time 2014/05/03
*/
public class WaitingListMonitor {
private Logger logger = Logger.getLogger(WaitingListMonitor.class);
public static final int DEFAULT_WAITING_LIST_MONTOR_INTERVAL = 10000;
private static final int DO_WITH_TIMEOUT = 0x01;
private Monitor mMonitor;
private static MonitorHandler mHandler;
private volatile boolean mStoped = false;
private volatile boolean mStarted = false;
public WaitingListMonitor(int interval) {
if (interval <= 0) {
logger.w("Set interval time of monitor less than 0!");
mMonitor = new Monitor("IM-waiting-list-monitor", Process.THREAD_PRIORITY_BACKGROUND,
DEFAULT_WAITING_LIST_MONTOR_INTERVAL);
} else {
mMonitor = new Monitor("IM-waiting-list-monitor", Process.THREAD_PRIORITY_BACKGROUND,
interval);
}
mHandler = new MonitorHandler(Looper.getMainLooper());
}
public synchronized void start() {
if (mStarted)
return;
mStoped = false;
mMonitor.start();
logger.d("start WaitingListMonitor!");
mStarted = true;
}
public synchronized void stop() {
if (mStoped) {
return;
}
mStoped = true;
mStarted = false;
mHandler.removeMessages(DO_WITH_TIMEOUT);
}
private class Monitor extends Thread {
private int mInterval;
public Monitor(String name, int priority, int interval) {
setName(name);
setPriority(priority);
mInterval = interval;
}
@Override
public void run() {
super.run();
try {
while (!mStoped) {
Map<Integer, Action> list = SocketMessageQueue
.getInstance().getWaitingList();
synchronized (list) {
final long currentTime = System.currentTimeMillis();
ArrayList<Action> timeoutList = null;
Iterator<Entry<Integer, Action>> iterator = list.entrySet().iterator();
while (iterator.hasNext()) {
Entry<Integer, Action> entry = iterator.next();
Action action = entry.getValue();
final int key = entry.getKey();
final long timeStamp = action.getTimeStamp();
final int timeout = action.getTimeout();
// int sid = action.getPacket().getRequest()
// .getHeader().getServiceId();
// int cid = action.getPacket().getRequest()
// .getHeader().getCommandId();
if (timeStamp + timeout < currentTime) {
list.remove(key);
// 重放入队列
if (action.minusRepeatCountIfFaild() >= 0) {
SocketMessageQueue.getInstance()
.submitAndEnqueue(action);
} else {
// 被判定为超时
if (null == timeoutList) {
timeoutList = new ArrayList<Action>();
timeoutList.add(action);
}
}
}
}
if (timeoutList != null) {
Message msg = mHandler.obtainMessage(
DO_WITH_TIMEOUT, timeoutList);
mHandler.sendMessage(msg);
}
}
sleep(mInterval);
}
} catch (Exception e) {
logger.e(e.getMessage());
}
}
}
private class MonitorHandler extends Handler {
public MonitorHandler(Looper looper) {
super(looper);
}
@SuppressWarnings("unchecked")
@Override
public void handleMessage(Message msg) {
if (msg.what == DO_WITH_TIMEOUT) {
ArrayList<Action> timeoutList = (ArrayList<Action>) msg.obj;
for (Action action : timeoutList) {
if (null == action) {
continue;
}
final ActionCallback callback = action.getCallback();
if (null != callback) {
callback.onTimeout(action.getPacket());
}
}
}
super.handleMessage(msg);
}
}
}