package org.rzo.netty.ahessian.timeout;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.rzo.netty.ahessian.Constants;
abstract class AbstractHeartBeatHandler extends SimpleChannelHandler
{
final ScheduledExecutorService _executor;
final long _timeout;
volatile long _lastCalled;
volatile boolean _connected = false;
volatile ChannelHandlerContext _ctx;
volatile ScheduledFuture _future;
public AbstractHeartBeatHandler(ScheduledExecutorService executor, long timeout)
{
_executor = executor;
_timeout = timeout;
}
abstract void timedOut(ChannelHandlerContext ctx);
long getLastCalled()
{
return _lastCalled;
}
boolean isConnected()
{
return _connected;
}
public void channelDisconnected(
ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
_connected = false;
if (_future != null)
_future.cancel(true);
_future = null;
}
protected void ping()
{
_lastCalled = System.currentTimeMillis();
}
public void channelConnected(
ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
_lastCalled = System.currentTimeMillis();
_ctx = ctx;
_connected = true;
Runnable command = new Runnable()
{
public void run()
{
if (isConnected())
{
if (getLastCalled() + _timeout < System.currentTimeMillis())
try
{
timedOut(_ctx);
}
catch (Exception e)
{
Constants.ahessianLogger.warn("", e);
}
}
}
};
_future = _executor.scheduleWithFixedDelay(command, _timeout, _timeout, TimeUnit.MILLISECONDS);
ctx.sendUpstream(e);
}
}