/**
* Dianping.com Inc.
* Copyright (c) 2003-2013 All Rights Reserved.
*/
package com.dianping.pigeon.remoting.invoker.listener;
import java.util.Map;
import com.dianping.pigeon.config.ConfigManagerLoader;
import com.dianping.pigeon.log.Logger;
import com.dianping.pigeon.log.LoggerLoader;
import com.dianping.pigeon.remoting.common.domain.InvocationRequest;
import com.dianping.pigeon.remoting.invoker.concurrent.Callback;
import com.dianping.pigeon.remoting.invoker.domain.RemoteInvocationBean;
import com.dianping.pigeon.remoting.invoker.route.statistics.ServiceStatisticsHolder;
public class InvocationTimeoutListener implements Runnable {
private static final Logger logger = LoggerLoader.getLogger(InvocationTimeoutListener.class);
private Map<Long, RemoteInvocationBean> invocations;
private long timeoutInterval = ConfigManagerLoader.getConfigManager().getLongValue(
"pigeon.invoker.timeout.interval", 1000);
public InvocationTimeoutListener(Map<Long, RemoteInvocationBean> invocations) {
this.invocations = invocations;
}
@Override
public void run() {
int timeoutCountInLastSecond = 0;
int timeoutCountInCurrentSecond = 0;
while (true) {
timeoutCountInLastSecond = timeoutCountInCurrentSecond;
timeoutCountInCurrentSecond = 0;
try {
Thread.sleep(timeoutInterval);
long currentTime = System.currentTimeMillis();
for (Long sequence : invocations.keySet()) {
RemoteInvocationBean invocationBean = invocations.get(sequence);
if (invocationBean != null) {
InvocationRequest request = invocationBean.request;
if (request.getTimeout() > 0 && request.getCreateMillisTime() > 0
&& request.getCreateMillisTime() + request.getTimeout() < currentTime) {
timeoutCountInCurrentSecond++;
Callback callback = invocationBean.callback;
if (callback != null && callback.getClient() != null) {
ServiceStatisticsHolder.flowOut(request, callback.getClient().getAddress());
}
if (callback != null) {
callback.dispose();
}
invocations.remove(sequence);
boolean isLog = true;
if (timeoutCountInLastSecond > ConfigManagerLoader.getConfigManager().getIntValue(
"pigeon.log.threshold", 10)
&& timeoutCountInCurrentSecond
% ConfigManagerLoader.getConfigManager().getIntValue("pigeon.log.interval",
10) != 1) {
isLog = false;
}
if (isLog) {
StringBuilder msg = new StringBuilder();
msg.append("remove timeout request, process time:").append(System.currentTimeMillis())
.append("\r\n").append("request:").append(request);
logger.warn(msg.toString());
// RequestTimeoutException e = new
// RequestTimeoutException(msg.toString());
// if (monitorLogger != null) {
// monitorLogger.logError(e);
// }
}
}
}
}
} catch (Throwable e) {
logger.warn("checking remote call timeout failed", e);
}
}
}
}