【问题标题】:Netty: How to make sure Channel.close() was fired by the I/O threadNetty:如何确保 Channel.close() 被 I/O 线程触发
【发布时间】:2013-04-28 14:21:24
【问题描述】:

我使用的是Netty 3.6.2,这是我的管道工厂伪代码:

private final static ThreadPoolExecutor executor = new OrderedMemoryAwareThreadPoolExecutor(8, 4194304, 4194304, 5L, TimeUnit.MINUTES);
public ChannelPipeline getPipeline() throws Exception {
    ChannelPipeline p = pipeline();
    p.addLast("frameDecoder", protobufFrameDecoder);
    p.addLast("protobufDecoder", protobufDecoder);
    p.addLast("executor", new ExecutionHandler(executor));
    p.addLast("handler", handler);
    p.addLast("frameEncoder", protobufFrameEncoder);
    p.addLast("protobufEncoder", protobufEncoder);
    return p;
}

这样,处理程序的messageReceived()在不同的线程池而不是工作线程池中被调用,现在我想关闭通道以防messageReceived()中发生一些异常,但根据这里:http://netty.io/wiki/thread-model.html

作为下游事件的副作用触发的任何上游事件 必须从 I/O 线程触发。

在exceptionCaught()中直接调用ctx.getChannel().close()是不安全的,我正在尝试用这种方式来解决这个问题,

NettyServerSocketFactory.getWorkerExecutor().execute(new Runnable() {
   @Override
   public void run() {
       channel.close();
   }
});

这里是 NettyServerSocketFactory 代码:

public class NettyServerSocketFactory extends NioServerSocketChannelFactory {

private static Executor bossExecutor = Executors.newCachedThreadPool();
private static Executor workerExecutor = Executors.newCachedThreadPool();

public static Executor getBossExecutor() {
    return bossExecutor;
}

public static Executor getWorkerExecutor() {
    return workerExecutor;
}

public NettyServerSocketFactory() {
    super(bossExecutor, workerExecutor);
}
}

但它似乎不起作用,任何建议将不胜感激。

【问题讨论】:

    标签: netty


    【解决方案1】:

    Channel#close() 触发一个最终到达 ChannelSink 的下游事件,该事件被“移交”给与该通道关联的工作人员以进行进一步处理。 worker 最终会触发一个通道关闭事件,worker 会确保事件在 IO 线程上向上游发送。

    这是它目前的工作方式,也许您所指的文档正在讨论以前的情况,事件确实是在调用线程上传递的。

    【讨论】:

      猜你喜欢
      • 2016-08-18
      • 2016-11-18
      • 2012-03-23
      • 1970-01-01
      • 2014-10-08
      • 2013-06-23
      • 1970-01-01
      • 2012-01-25
      • 1970-01-01
      相关资源
      最近更新 更多