Allow to recover from exception triggered by accept() more easily
This is done by stop accept() new sockets for 1 seconds Beside this this commit also makes sure accept() exceptions of OioServerSocketChannel trigger the fireExceptionCaught(...). The same is true fo the AioServerSocketChannel.
This commit is contained in:
parent
b65c8716a5
commit
18bda09d6c
@ -18,6 +18,7 @@ package io.netty.bootstrap;
|
|||||||
import io.netty.buffer.MessageBuf;
|
import io.netty.buffer.MessageBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelConfig;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundMessageHandler;
|
import io.netty.channel.ChannelInboundMessageHandler;
|
||||||
@ -35,6 +36,7 @@ import io.netty.util.internal.logging.InternalLoggerFactory;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Bootstrap} sub-class which allows easy bootstrap of {@link ServerChannel}
|
* {@link Bootstrap} sub-class which allows easy bootstrap of {@link ServerChannel}
|
||||||
@ -267,6 +269,25 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||||
|
final ChannelConfig config = ctx.channel().config();
|
||||||
|
if (config.isAutoRead()) {
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
// still let the exceptionCaught event flow through the pipeline to give the user
|
||||||
|
// a chance to do something with it
|
||||||
|
ctx.fireExceptionCaught(cause);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -216,6 +216,7 @@ public class AioServerSocketChannel extends AbstractAioChannel implements Server
|
|||||||
// log something
|
// log something
|
||||||
if (channel.isOpen() && ! asyncClosed) {
|
if (channel.isOpen() && ! asyncClosed) {
|
||||||
logger.warn("Failed to create a new channel from an accepted socket.", t);
|
logger.warn("Failed to create a new channel from an accepted socket.", t);
|
||||||
|
channel.pipeline().fireExceptionCaught(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,26 +160,26 @@ public class OioServerSocketChannel extends AbstractOioMessageChannel
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket s = null;
|
|
||||||
try {
|
try {
|
||||||
s = socket.accept();
|
Socket s = socket.accept();
|
||||||
if (s != null) {
|
try {
|
||||||
buf.add(new OioSocketChannel(this, null, s));
|
if (s != null) {
|
||||||
return 1;
|
buf.add(new OioSocketChannel(this, null, s));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
logger.warn("Failed to create a new channel from an accepted socket.", t);
|
||||||
|
if (s != null) {
|
||||||
|
try {
|
||||||
|
s.close();
|
||||||
|
} catch (Throwable t2) {
|
||||||
|
logger.warn("Failed to close a socket.", t2);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (SocketTimeoutException e) {
|
} catch (SocketTimeoutException e) {
|
||||||
// Expected
|
// Expected
|
||||||
} catch (Throwable t) {
|
|
||||||
logger.warn("Failed to create a new channel from an accepted socket.", t);
|
|
||||||
if (s != null) {
|
|
||||||
try {
|
|
||||||
s.close();
|
|
||||||
} catch (Throwable t2) {
|
|
||||||
logger.warn("Failed to close a socket.", t2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user