Ensure trying to recover from exceptionCaught on the ServerChannel works as expected

Motivation:

When "Too many open files" happens,the URLClassLoader cannot do any classloading because URLClassLoader need a FD  for findClass. Because of this the anonymous inner class that is created to re-enable auto read may cause a problem.

Modification:

Pre-create Runnable that is scheduled and so ensure it is not lazy loaded.

Result:

No more problems when try to recover.
This commit is contained in:
Hanson 2016-11-22 11:43:26 +08:00 committed by Norman Maurer
parent ad51cda2cd
commit d0a3877535

View File

@ -168,7 +168,7 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerCh
p.addLast(new ChannelInitializer<Channel>() {
@Override
public void initChannel(Channel ch) throws Exception {
public void initChannel(final Channel ch) throws Exception {
final ChannelPipeline pipeline = ch.pipeline();
ChannelHandler handler = config.handler();
if (handler != null) {
@ -183,7 +183,7 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerCh
@Override
public void run() {
pipeline.addLast(new ServerBootstrapAcceptor(
currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
}
});
}
@ -219,14 +219,27 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerCh
private final ChannelHandler childHandler;
private final Entry<ChannelOption<?>, Object>[] childOptions;
private final Entry<AttributeKey<?>, Object>[] childAttrs;
private final Runnable enableAutoReadTask;
ServerBootstrapAcceptor(
EventLoopGroup childGroup, ChannelHandler childHandler,
final Channel channel, EventLoopGroup childGroup, ChannelHandler childHandler,
Entry<ChannelOption<?>, Object>[] childOptions, Entry<AttributeKey<?>, Object>[] childAttrs) {
this.childGroup = childGroup;
this.childHandler = childHandler;
this.childOptions = childOptions;
this.childAttrs = childAttrs;
// Task which is scheduled to re-enable auto-read.
// It's important to create this Runnable before we try to submit it as otherwise the URLClassLoader may
// not be able to load the class because of the file limit it already reached.
//
// See https://github.com/netty/netty/issues/1328
enableAutoReadTask = new Runnable() {
@Override
public void run() {
channel.config().setAutoRead(true);
}
};
}
@Override
@ -268,12 +281,7 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerCh
// stop accept new connections for 1 second to allow the channel to recover
// See https://github.com/netty/netty/issues/1328
config.setAutoRead(false);
ctx.channel().eventLoop().schedule(new Runnable() {
@Override
public void run() {
config.setAutoRead(true);
}
}, 1, TimeUnit.SECONDS);
ctx.channel().eventLoop().schedule(enableAutoReadTask, 1, TimeUnit.SECONDS);
}
// still let the exceptionCaught event flow through the pipeline to give the user
// a chance to do something with it