Made IdleStateHandler @Sharable and removed unnecessary lazy
initialization in ReadTimeoutHandler
This commit is contained in:
parent
f22a55d6e2
commit
fd7b5769f7
@ -21,6 +21,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
import org.jboss.netty.bootstrap.ServerBootstrap;
|
import org.jboss.netty.bootstrap.ServerBootstrap;
|
||||||
import org.jboss.netty.channel.Channel;
|
import org.jboss.netty.channel.Channel;
|
||||||
|
import org.jboss.netty.channel.ChannelHandler;
|
||||||
|
import org.jboss.netty.channel.ChannelHandler.Sharable;
|
||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||||
import org.jboss.netty.channel.ChannelPipeline;
|
import org.jboss.netty.channel.ChannelPipeline;
|
||||||
import org.jboss.netty.channel.ChannelPipelineFactory;
|
import org.jboss.netty.channel.ChannelPipelineFactory;
|
||||||
@ -73,14 +75,16 @@ import org.jboss.netty.util.TimerTask;
|
|||||||
* public class MyPipelineFactory implements {@link ChannelPipelineFactory} {
|
* public class MyPipelineFactory implements {@link ChannelPipelineFactory} {
|
||||||
*
|
*
|
||||||
* private final {@link Timer} timer;
|
* private final {@link Timer} timer;
|
||||||
|
* private final {@link ChannelHandler} idleStateHandler;
|
||||||
*
|
*
|
||||||
* public MyPipelineFactory({@link Timer} timer) {
|
* public MyPipelineFactory({@link Timer} timer) {
|
||||||
* this.timer = timer;
|
* this.timer = timer;
|
||||||
|
* this.idleStateHandler = <b>new {@link IdleStateHandler}(timer, 60, 30, 0), // timer must be shared.</b>
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* public {@link ChannelPipeline} getPipeline() {
|
* public {@link ChannelPipeline} getPipeline() {
|
||||||
* return {@link Channels}.pipeline(
|
* return {@link Channels}.pipeline(
|
||||||
* <b>new {@link IdleStateHandler}(timer, 60, 30, 0), // timer must be shared.</b>
|
* idleStateHandler,
|
||||||
* new MyHandler());
|
* new MyHandler());
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
@ -120,6 +124,7 @@ import org.jboss.netty.util.TimerTask;
|
|||||||
* @apiviz.uses org.jboss.netty.util.HashedWheelTimer
|
* @apiviz.uses org.jboss.netty.util.HashedWheelTimer
|
||||||
* @apiviz.has org.jboss.netty.handler.timeout.IdleStateEvent oneway - - triggers
|
* @apiviz.has org.jboss.netty.handler.timeout.IdleStateEvent oneway - - triggers
|
||||||
*/
|
*/
|
||||||
|
@Sharable
|
||||||
public class IdleStateHandler extends SimpleChannelUpstreamHandler
|
public class IdleStateHandler extends SimpleChannelUpstreamHandler
|
||||||
implements LifeCycleAwareChannelHandler,
|
implements LifeCycleAwareChannelHandler,
|
||||||
ExternalResourceReleasable {
|
ExternalResourceReleasable {
|
||||||
@ -127,15 +132,8 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler
|
|||||||
final Timer timer;
|
final Timer timer;
|
||||||
|
|
||||||
final long readerIdleTimeMillis;
|
final long readerIdleTimeMillis;
|
||||||
volatile Timeout readerIdleTimeout;
|
|
||||||
volatile long lastReadTime;
|
|
||||||
|
|
||||||
final long writerIdleTimeMillis;
|
final long writerIdleTimeMillis;
|
||||||
volatile Timeout writerIdleTimeout;
|
|
||||||
volatile long lastWriteTime;
|
|
||||||
|
|
||||||
final long allIdleTimeMillis;
|
final long allIdleTimeMillis;
|
||||||
volatile Timeout allIdleTimeout;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
@ -249,7 +247,7 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeRemove(ChannelHandlerContext ctx) throws Exception {
|
public void beforeRemove(ChannelHandlerContext ctx) throws Exception {
|
||||||
destroy();
|
destroy(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -270,14 +268,15 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler
|
|||||||
@Override
|
@Override
|
||||||
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
|
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
destroy();
|
destroy(ctx);
|
||||||
ctx.sendUpstream(e);
|
ctx.sendUpstream(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
|
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
lastReadTime = System.currentTimeMillis();
|
State state = (State) ctx.getAttachment();
|
||||||
|
state.lastReadTime = System.currentTimeMillis();
|
||||||
ctx.sendUpstream(e);
|
ctx.sendUpstream(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,42 +284,47 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler
|
|||||||
public void writeComplete(ChannelHandlerContext ctx, WriteCompletionEvent e)
|
public void writeComplete(ChannelHandlerContext ctx, WriteCompletionEvent e)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
if (e.getWrittenAmount() > 0) {
|
if (e.getWrittenAmount() > 0) {
|
||||||
lastWriteTime = System.currentTimeMillis();
|
State state = (State) ctx.getAttachment();
|
||||||
|
state.lastWriteTime = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
ctx.sendUpstream(e);
|
ctx.sendUpstream(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initialize(ChannelHandlerContext ctx) {
|
private void initialize(ChannelHandlerContext ctx) {
|
||||||
lastReadTime = lastWriteTime = System.currentTimeMillis();
|
State state = new State();
|
||||||
|
ctx.setAttachment(state);
|
||||||
|
|
||||||
|
state.lastReadTime = state.lastWriteTime = System.currentTimeMillis();
|
||||||
if (readerIdleTimeMillis > 0) {
|
if (readerIdleTimeMillis > 0) {
|
||||||
readerIdleTimeout = timer.newTimeout(
|
state.readerIdleTimeout = timer.newTimeout(
|
||||||
new ReaderIdleTimeoutTask(ctx),
|
new ReaderIdleTimeoutTask(ctx),
|
||||||
readerIdleTimeMillis, TimeUnit.MILLISECONDS);
|
readerIdleTimeMillis, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
if (writerIdleTimeMillis > 0) {
|
if (writerIdleTimeMillis > 0) {
|
||||||
writerIdleTimeout = timer.newTimeout(
|
state.writerIdleTimeout = timer.newTimeout(
|
||||||
new WriterIdleTimeoutTask(ctx),
|
new WriterIdleTimeoutTask(ctx),
|
||||||
writerIdleTimeMillis, TimeUnit.MILLISECONDS);
|
writerIdleTimeMillis, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
if (allIdleTimeMillis > 0) {
|
if (allIdleTimeMillis > 0) {
|
||||||
allIdleTimeout = timer.newTimeout(
|
state.allIdleTimeout = timer.newTimeout(
|
||||||
new AllIdleTimeoutTask(ctx),
|
new AllIdleTimeoutTask(ctx),
|
||||||
allIdleTimeMillis, TimeUnit.MILLISECONDS);
|
allIdleTimeMillis, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void destroy() {
|
private void destroy(ChannelHandlerContext ctx) {
|
||||||
if (readerIdleTimeout != null) {
|
State state = (State) ctx.getAttachment();
|
||||||
readerIdleTimeout.cancel();
|
if (state.readerIdleTimeout != null) {
|
||||||
readerIdleTimeout = null;
|
state.readerIdleTimeout.cancel();
|
||||||
|
state.readerIdleTimeout = null;
|
||||||
}
|
}
|
||||||
if (writerIdleTimeout != null) {
|
if (state.writerIdleTimeout != null) {
|
||||||
writerIdleTimeout.cancel();
|
state.writerIdleTimeout.cancel();
|
||||||
writerIdleTimeout = null;
|
state.writerIdleTimeout = null;
|
||||||
}
|
}
|
||||||
if (allIdleTimeout != null) {
|
if (state.allIdleTimeout != null) {
|
||||||
allIdleTimeout.cancel();
|
state.allIdleTimeout.cancel();
|
||||||
allIdleTimeout = null;
|
state.allIdleTimeout = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,12 +347,13 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
State state = (State) ctx.getAttachment();
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
long lastReadTime = IdleStateHandler.this.lastReadTime;
|
long lastReadTime = state.lastReadTime;
|
||||||
long nextDelay = readerIdleTimeMillis - (currentTime - lastReadTime);
|
long nextDelay = readerIdleTimeMillis - (currentTime - lastReadTime);
|
||||||
if (nextDelay <= 0) {
|
if (nextDelay <= 0) {
|
||||||
// Reader is idle - set a new timeout and notify the callback.
|
// Reader is idle - set a new timeout and notify the callback.
|
||||||
readerIdleTimeout =
|
state.readerIdleTimeout =
|
||||||
timer.newTimeout(this, readerIdleTimeMillis, TimeUnit.MILLISECONDS);
|
timer.newTimeout(this, readerIdleTimeMillis, TimeUnit.MILLISECONDS);
|
||||||
try {
|
try {
|
||||||
channelIdle(ctx, IdleState.READER_IDLE, lastReadTime);
|
channelIdle(ctx, IdleState.READER_IDLE, lastReadTime);
|
||||||
@ -357,7 +362,7 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Read occurred before the timeout - set a new timeout with shorter delay.
|
// Read occurred before the timeout - set a new timeout with shorter delay.
|
||||||
readerIdleTimeout =
|
state.readerIdleTimeout =
|
||||||
timer.newTimeout(this, nextDelay, TimeUnit.MILLISECONDS);
|
timer.newTimeout(this, nextDelay, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -378,12 +383,13 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
State state = (State) ctx.getAttachment();
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
long lastWriteTime = IdleStateHandler.this.lastWriteTime;
|
long lastWriteTime = state.lastWriteTime;
|
||||||
long nextDelay = writerIdleTimeMillis - (currentTime - lastWriteTime);
|
long nextDelay = writerIdleTimeMillis - (currentTime - lastWriteTime);
|
||||||
if (nextDelay <= 0) {
|
if (nextDelay <= 0) {
|
||||||
// Writer is idle - set a new timeout and notify the callback.
|
// Writer is idle - set a new timeout and notify the callback.
|
||||||
writerIdleTimeout =
|
state.writerIdleTimeout =
|
||||||
timer.newTimeout(this, writerIdleTimeMillis, TimeUnit.MILLISECONDS);
|
timer.newTimeout(this, writerIdleTimeMillis, TimeUnit.MILLISECONDS);
|
||||||
try {
|
try {
|
||||||
channelIdle(ctx, IdleState.WRITER_IDLE, lastWriteTime);
|
channelIdle(ctx, IdleState.WRITER_IDLE, lastWriteTime);
|
||||||
@ -392,7 +398,7 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Write occurred before the timeout - set a new timeout with shorter delay.
|
// Write occurred before the timeout - set a new timeout with shorter delay.
|
||||||
writerIdleTimeout =
|
state.writerIdleTimeout =
|
||||||
timer.newTimeout(this, nextDelay, TimeUnit.MILLISECONDS);
|
timer.newTimeout(this, nextDelay, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,13 +418,14 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
State state = (State) ctx.getAttachment();
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
long lastIoTime = Math.max(lastReadTime, lastWriteTime);
|
long lastIoTime = Math.max(state.lastReadTime, state.lastWriteTime);
|
||||||
long nextDelay = allIdleTimeMillis - (currentTime - lastIoTime);
|
long nextDelay = allIdleTimeMillis - (currentTime - lastIoTime);
|
||||||
if (nextDelay <= 0) {
|
if (nextDelay <= 0) {
|
||||||
// Both reader and writer are idle - set a new timeout and
|
// Both reader and writer are idle - set a new timeout and
|
||||||
// notify the callback.
|
// notify the callback.
|
||||||
allIdleTimeout =
|
state.allIdleTimeout =
|
||||||
timer.newTimeout(this, allIdleTimeMillis, TimeUnit.MILLISECONDS);
|
timer.newTimeout(this, allIdleTimeMillis, TimeUnit.MILLISECONDS);
|
||||||
try {
|
try {
|
||||||
channelIdle(ctx, IdleState.ALL_IDLE, lastIoTime);
|
channelIdle(ctx, IdleState.ALL_IDLE, lastIoTime);
|
||||||
@ -428,9 +435,23 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler
|
|||||||
} else {
|
} else {
|
||||||
// Either read or write occurred before the timeout - set a new
|
// Either read or write occurred before the timeout - set a new
|
||||||
// timeout with shorter delay.
|
// timeout with shorter delay.
|
||||||
allIdleTimeout =
|
state.allIdleTimeout =
|
||||||
timer.newTimeout(this, nextDelay, TimeUnit.MILLISECONDS);
|
timer.newTimeout(this, nextDelay, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class State {
|
||||||
|
State() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
volatile Timeout readerIdleTimeout;
|
||||||
|
volatile long lastReadTime;
|
||||||
|
|
||||||
|
volatile Timeout writerIdleTimeout;
|
||||||
|
volatile long lastWriteTime;
|
||||||
|
|
||||||
|
volatile Timeout allIdleTimeout;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,29 +189,19 @@ public class ReadTimeoutHandler extends SimpleChannelUpstreamHandler
|
|||||||
@Override
|
@Override
|
||||||
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
|
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
updateLastReadTime(ctx);
|
State state = (State) ctx.getAttachment();
|
||||||
|
state.lastReadTime = System.currentTimeMillis();
|
||||||
ctx.sendUpstream(e);
|
ctx.sendUpstream(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initialize(ChannelHandlerContext ctx) {
|
private void initialize(ChannelHandlerContext ctx) {
|
||||||
updateLastReadTime(ctx);
|
State state = new State();
|
||||||
|
ctx.setAttachment(state);
|
||||||
if (timeoutMillis > 0) {
|
if (timeoutMillis > 0) {
|
||||||
State state = (State) ctx.getAttachment();
|
|
||||||
state.timeout = timer.newTimeout(new ReadTimeoutTask(ctx), timeoutMillis, TimeUnit.MILLISECONDS);
|
state.timeout = timer.newTimeout(new ReadTimeoutTask(ctx), timeoutMillis, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLastReadTime(ChannelHandlerContext ctx) {
|
|
||||||
State state = (State) ctx.getAttachment();
|
|
||||||
if (state == null) {
|
|
||||||
// lastReadTime will be set by the constructor, so we do not do it
|
|
||||||
// again here.
|
|
||||||
ctx.setAttachment(state = new State());
|
|
||||||
} else {
|
|
||||||
state.lastReadTime = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void destroy(ChannelHandlerContext ctx) {
|
private void destroy(ChannelHandlerContext ctx) {
|
||||||
State state = (State) ctx.getAttachment();
|
State state = (State) ctx.getAttachment();
|
||||||
if (state.timeout != null) {
|
if (state.timeout != null) {
|
||||||
|
Loading…
Reference in New Issue
Block a user