I need my messageReceived (or channelRead0 for netty 4.0) method in my ChannelHandler to timeout after a certain time threshold. I have tried Read/WriteTimeoutHandlers, but couldn't generate an exception when my messageReceived processing time exceeded the timeout. Here's what I tried:
public class HttpServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) {
ChannelPipeline p = ch.pipeline();
p.addLast(new HttpRequestDecoder());
p.addLast(new HttpResponseEncoder());
p.addLast(new HttpObjectAggregator(1048576));
p.addLast(new HttpContentCompressor());
p.addLast("readTimeoutHandler", new ReadTimeoutHandler(1));
//p.addLast("idleTimeoutHandler", new IdleStateHandler(1, 1, 1));
p.addLast(new HttpRequestHandler());
}
}
public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
public static class Call implements Callable<Boolean> {
public Boolean call() {
for(long i = 0; i<100000000;i++){
for(long j = 0; j<100;j++){
}
}
return true;
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
System.out.println("** Exception caught **");
if (cause instanceof ReadTimeoutException) {
System.out.println("*** Request timed out ***");
}
else if (cause instanceof WriteTimeoutException) {
System.out.println("*** Request timed out on write ***");
}
cause.printStackTrace();
ctx.close();
}
@Override
public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
FullHttpRequest request = this.request = (FullHttpRequest) msg;
/*Callable<Boolean> callable = new Call();
ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
ScheduledFuture<Boolean> handle = scheduler.schedule(callable, 4, TimeUnit.SECONDS);
boolean v = handle.get();*/
for(long i = 0; i<100000000;i++){
for(long j = 0; j<100;j++){
}
}
System.out.println("Wait done");
try{
CharSequence content = appController.handleRequest(
url,
ctx.channel().remoteAddress().toString(),
parseURL(url), reqBody);
if(content!=null){
writeResponse(ctx, HttpResponseStatus.OK, content);
}
}catch(AppRuntimeException e){
CharSequence content = e.getMessage();
if(content != null){
OptHttpStatus status = e.getOptHttpStatus();
writeResponse(ctx, HttpResponseStatus.valueOf(status.getCode()), content);
}
}
private void writeResponse(ChannelHandlerContext ctx, HttpResponseStatus status, CharSequence content) {
// Decide whether to close the connection or not.
boolean keepAlive = HttpUtil.isKeepAlive(request);
// Build the response object.
FullHttpResponse response = new DefaultFullHttpResponse(
HTTP_1_1,
status,
Unpooled.copiedBuffer(content, CharsetUtil.UTF_8));
//Unpooled.copiedBuffer(buf.toString(), CharsetUtil.UTF_8));
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
response.headers().set("Access-Control-Allow-Origin", "*");
if (keepAlive) {
//Add 'Content-Length' header only for a keep-alive connection.
response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
// Add keep alive header as per:
// - http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Connection
response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
}
// Write the response.
ChannelFuture ch = ctx.writeAndFlush(response);
if(!keepAlive){
ch.addListener(ChannelFutureListener.CLOSE);
}
}
}
I added a redundant for loop for simulating wait in channelRead0 method to simulate long processing time. But a timeout exception was not generated. I also tried scheduling the wait, but didn't get a timeout exception Can you suggest any solutions?