• write异步与流量控制 4.0.29.Final


    AbstractChannelHandlerContext.class

        private void write(Object msg, boolean flush, ChannelPromise promise) {
            AbstractChannelHandlerContext next = this.findContextOutbound();
            EventExecutor executor = next.executor();
            if(executor.inEventLoop()) {
                next.invokeWrite(msg, promise);
                if(flush) {
                    next.invokeFlush();
                }
            } else {
                int size = this.channel.estimatorHandle().size(msg);
                if(size > 0) {
                    ChannelOutboundBuffer task = this.channel.unsafe().outboundBuffer();
                    if(task != null) {
                        task.incrementPendingOutboundBytes((long)size);
                    }
                }
    
                Object task1;
                if(flush) {
                    task1 = AbstractChannelHandlerContext.WriteAndFlushTask.newInstance(next, msg, size, promise);
                } else {
                    task1 = AbstractChannelHandlerContext.WriteTask.newInstance(next, msg, size, promise);
                }
    
                safeExecute(executor, (Runnable)task1, promise, msg);
            }
    
        }
    

     对于write操作,会先判断下一个outboundhandler的执行线程是否是当前线程

    public abstract class AbstractEventExecutor extends AbstractExecutorService implements EventExecutor {
        public AbstractEventExecutor() {
        }
    
        public EventExecutor next() {
            return this;
        }
    
        public boolean inEventLoop() {
            return this.inEventLoop(Thread.currentThread());
        }
     
    

     如果是,则使用next outboundhandler执行invokewrite

        private void invokeWrite(Object msg, ChannelPromise promise) {
            try {
                ((ChannelOutboundHandler)this.handler()).write(this, msg, promise);
            } catch (Throwable var4) {
                notifyOutboundHandlerException(var4, promise);
            }
    
        }
    

     如果不是则让next outboundhandler所在线程池EventExecutor执行一个task

        private static void safeExecute(EventExecutor executor, Runnable runnable, ChannelPromise promise, Object msg) {
            try {
                executor.execute(runnable);
            } catch (Throwable var9) {
                Throwable cause = var9;
    
                try {
                    promise.setFailure(cause);
                } finally {
                    if(msg != null) {
                        ReferenceCountUtil.release(msg);
                    }
    
                }
            }
    
        }
    

     execute一个任务,异常则释放msg

    abstract static class AbstractWriteTask extends RecyclableMpscLinkedQueueNode<Runnable> implements Runnable {
    。。。。。。
    
            public final void run() {
                try {
                    if(this.size > 0) {
                        ChannelOutboundBuffer buffer = this.ctx.channel.unsafe().outboundBuffer();
                        if(buffer != null) {
                            buffer.decrementPendingOutboundBytes((long)this.size);
                        }
                    }
    
                    this.write(this.ctx, this.msg, this.promise);
                } finally {
                    this.ctx = null;
                    this.msg = null;
                    this.promise = null;
                }
    
            }
    

    对于业务线程write,当时先增加水位,run时减少水位

    到底层

    DefaultChannelPipeline.HeadHandler

            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                this.unsafe.write(msg, promise);
            }
    
            public void flush(ChannelHandlerContext ctx) throws Exception {
                this.unsafe.flush();
            }
    
            HeadContext(DefaultChannelPipeline pipeline) {
                super(pipeline, (EventExecutorGroup)null, HEAD_NAME, false, true);
                this.unsafe = pipeline.channel().unsafe();
            }
    

      

    AbstractChannel.class

        protected AbstractChannel(Channel parent) {
            this.parent = parent;
            this.unsafe = this.newUnsafe();
            this.pipeline = new DefaultChannelPipeline(this);
        }
    

      

    protected abstract AbstractChannel.AbstractUnsafe newUnsafe();
    

      

    AbstractChannel.AbastraceUnsafe:

            public final void write(Object msg, ChannelPromise promise) {
                ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
                if(outboundBuffer == null) {
                    this.safeSetFailure(promise, AbstractChannel.CLOSED_CHANNEL_EXCEPTION);
                    ReferenceCountUtil.release(msg);
                } else {
                    int size;
                    try {
                        msg = AbstractChannel.this.filterOutboundMessage(msg);
                        size = AbstractChannel.this.estimatorHandle().size(msg);
                        if(size < 0) {
                            size = 0;
                        }
                    } catch (Throwable var6) {
                        this.safeSetFailure(promise, var6);
                        ReferenceCountUtil.release(msg);
                        return;
                    }
    
                    outboundBuffer.addMessage(msg, size, promise);
                }
            }
    

     异常则释放msg

    可以看到,最终调用ChannelOutboundBuffer.addMessage

        public void addMessage(Object msg, int size, ChannelPromise promise) {
            ChannelOutboundBuffer.Entry entry = ChannelOutboundBuffer.Entry.newInstance(msg, size, total(msg), promise);
            if(this.tailEntry == null) {
                this.flushedEntry = null;
                this.tailEntry = entry;
            } else {
                ChannelOutboundBuffer.Entry tail = this.tailEntry;
                tail.next = entry;
                this.tailEntry = entry;
            }
    
            if(this.unflushedEntry == null) {
                this.unflushedEntry = entry;
            }
    
            this.incrementPendingOutboundBytes((long)size, false);
        }
    

    又增加水位,所以业务线程write会经历增加-减少-增加 3次,而在io线程write只会增加1次

  • 相关阅读:
    利用iframe实现ajax 跨域通信的解决方案
    C++中事件机制的简洁实现
    java远程类加载与轻客户端
    iOS开发那些事性能优化–内存泄露问题的解决
    Asp.net项目的开发流程
    LVS配置教程
    PowerShell之东扯西谈
    响应式设计专题
    2013年最值得关注的网页设计流行趋势
    HTTP Live Streaming直播技术分析与实现
  • 原文地址:https://www.cnblogs.com/silyvin/p/12147569.html
Copyright © 2020-2023  润新知