Netty Writeandflush () process and asynchronous

Source: Internet
Author: User

Netty Writeandflush () method is divided into two steps, first write and then flush

    @Override public    channelfuture Writeandflush (Object msg, Channelpromise promise) {        Defaultchannelhandlercontext Next;        Next = Findcontextoutbound (mask_write);        Referencecountutil.touch (msg, next);        Next.invoker.invokeWrite (Next, MSG, promise);        Next = Findcontextoutbound (Mask_flush);        Next.invoker.invokeFlush (next);        return promise;    }

The above is the Writeandflush method in Defaultchannelhandlercontext, which is actually called write first, and then the flush

1. Write

The Write method starts with Tailhandler, passes through the various handler of the middle custom and then arrives at Headhandler, and then calls the member variable of the Headhandler unsafe's write

As follows

        @Override public        void Write (Object msg, Channelpromise Promise) {            Channeloutboundbuffer Outboundbuffer = This.outboundbuffer;            if (Outboundbuffer = = null) {                //If the outboundbuffer is null we know the channel were closed                and so//need to FA Il the future right away. If It is not null the handling of the rest//would be do in                flush0 ()                //See Https://github.com/netty/netty/issue s/2362                safesetfailure (Promise, closed_channel_exception);                Release message now to prevent Resource-leak                referencecountutil.release (msg);                return;            }            Outboundbuffer.addmessage (msg, promise);        }

Will eventually put the need to write MSG and promise (that is, a future, we take the future of the hand, add listener is also this) into the Outboundbuffer, The existence form of MSG and promise in Outboundbuffer is a custom structure entry.

This means that calling the Write method actually does not really write the message, but instead puts the message and the promise of the operation into a queue.

2. Flush

Flush is also starting from tail, finally to head, the final call is also the head of the unsafe Flush0 () method, and then Flush0 () call the Dowrite () method, as follows:

@Override protected void Dowrite (Channeloutboundbuffer in) throws Exception {int writespincount =-1; for (;;)            {Object msg = in.current ();                if (msg = = NULL) {//wrote all messages.                Clearopwrite ();            Break                } if (msg instanceof bytebuf) {bytebuf buf = (bytebuf) msg;                int readablebytes = Buf.readablebytes ();                    if (readablebytes = = 0) {in.remove ();                Continue                } Boolean setopwrite = false;                Boolean done = false;                Long Flushedamount = 0;                if (Writespincount = =-1) {writespincount = config (). Getwritespincount (); } for (int i = writeSpinCount-1; I >= 0; I-) {int localflushedamount = dowritebytes (BUF);This is where the actual data is written out if (Localflushedamount = = 0) {Setopwrite = true;                    Break                    } Flushedamount + = Localflushedamount;                        if (!buf.isreadable ()) {done = true;                    Break                }} in.progress (Flushedamount);                if (done) {in.remove ();                    } else {incompletewrite (setopwrite);                Break                }} else if (msg instanceof fileregion) {fileregion region = (fileregion) msg;                Boolean setopwrite = false;                Boolean done = false;                Long Flushedamount = 0;                if (Writespincount = =-1) {writespincount = config (). Getwritespincount (); } for (int i = writeSpinCount-1; I >= 0; i-) {long Localflushedamount = dowritefileregion (region);                        if (Localflushedamount = = 0) {Setopwrite = true;                    Break                    } Flushedamount + = Localflushedamount;                        if (region.transfered () >= Region.count ()) {done = true;                    Break                }} in.progress (Flushedamount);                     if (done) {In.remove ();Depending on the number of data written out, determine whether the operation is complete, and if it is done, call In.remove ()} else {incompletewrite (setopwrite);                Break }} else {throw new Unsupportedoperationexception ("Unsupported message type:" + Stringutil.sim            Pleclassname (msg)); }        }    }

The Scarlet Letter is the last place to write the data, and here the data is finally called the Gatheringbytechannel write () method, which is a native Java interface that relies on the Java class that implements the interface, such as the Socketcha that invokes NIO. Nnel's Write () method, so far, the actual process of writing data appears, Socketchannel can run in non-blocking mode, that is, non-blocking asynchronous mode, write data will immediately return the amount of data written (not necessarily all the data is written successfully, For all data written, Netty has its own processing logic, that is, the red word in the above code for the loop, specific to the next Socketchannel Javadoc and Netty source).

When all data is written to Socketchannel success, start calling In.remove (), this in is the first step 1. The Outboundbuffer in write, his type is Channeloutboundbuffer, the code is as follows:

    Public final Boolean remove () {        if (IsEmpty ()) {            return false;        }        Entry e = buffer[flushed];        Object msg = e.msg;        if (msg = = null) {            return false;        }        Channelpromise promise = E.promise;        int size = E.pendingsize;        E.clear ();        flushed = flushed + 1 & buffer.length-1;        if (!e.cancelled) {            //Only release message, notify and decrement if it is not canceled before.            Saferelease (msg);            Safesuccess (Promise); Here, the Promise Trysuccess () method is called, triggering the listener            decrementpendingoutboundbytes (size);        }        return true;    }

Finally, the Promise notifylisteners () operation is called, triggering the listener to complete the asynchronous process

---------

Finally, go back to the code we used when we applied Netty.

@Override public    void Channelread (Channelhandlercontext ctx, Object msg) {                Ctx.writeandflush (new Object ()). AddListener (New Channelfuturelistener () {            @Override public            void Operationcomplete (Channelfuture the Future) Throws Exception {                if (future.issuccess ()) {                    //do sth                } else {                    //do Sth                }}}        );    }

That's the whole process.

Finally mention, Netty Abstractniochannel encapsulated Selectionkey, in the accept socket, the socket will be registered to EventLoop () selector, This selectionkey will be assigned, as follows

Selectionkey = Javachannel (). Register (EventLoop (). Selector, 0, this);

In the later selector select (), this key will be taken to the channel, and then call Abstractchannel in the Defaultchannelpipeline to trigger the Handler Connect, Rea D, write, etc. events ...

Netty Writeandflush () process and async

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.