8 Replies Latest reply on Jul 31, 2008 7:46 AM by timfox

    Message Chunking

    ataylor

      Ive created a new Branch with the new Message Chunking code rolled in to Tim's new Remoting code. http://anonsvn.jboss.org/repos/messaging/branches/Branch_Message_Chunking_new/.

      If you look at RemotingConnectionImpl/RemotingHandlerImpl you'll see a new class PacketAssembler. Basically this assembles/disassembles the packets into smaller buffers. Each buffer is written to the session in the normal fashion.

      There are 2 new configuration attributes 'remoting-initial-packet-fragment-size', which is the size to make the initial packet sent and 'remoting-packet-fragment-size' for any subsequent packets. setting the latter to 0 will also revert back to using 1 buffer.

      There has been a drop in our performance figures because of this, so I'm currently investigating this. I know for large messages that encoding is actually quicker, i think because we don't need to auto expand buffers, but i havent got as far as checking the decoding.

        • 1. Re: Message Chunking
          timfox

          One thing I noticed is that RemotingServiceImpl and PacketAssemblerImpl have references to a PacketFragmentCache but don't do anything with it.

          The only place that uses the cache is PacketFragmentImpl

          • 2. Re: Message Chunking
            timfox

            I have to say I don't really understand why you don't just put the conversion to List in the encode method of the Packet - not sure I see that PacketAssembler/Disassembler is necessary.

            Another observation is that messages are just being re-encoded into several buffers. The original idea here was to write directly into the messages own buffers when the user builds the message and then just use that when writing to the wire - no re-writing necessary.

            I'm nor sure we need PacketFragment either - can't we just use MessagingBuffer?

            Regarding re-assembling, I'm not sure this is necessary either since when reading several packets off the wire to form a command we can just store the actual buffers, no need to re-assemble?

            • 3. Re: Message Chunking
              ataylor

               

              I have to say I don't really understand why you don't just put the conversion to List in the encode method of the Packet - not sure I see that PacketAssembler/Disassembler is necessary.


              could do, but i don't think the Packet should care about how messages are broken up.

              Another observation is that messages are just being re-encoded into several buffers. The original idea here was to write directly into the messages own buffers when the user builds the message and then just use that when writing to the wire - no re-writing necessary.


              yes, at the minute they do. this still needs changing. Doing it this way tho' means that every message is still split up into 2 messages since the body is always written before the packet headers etc. I was thinking about changing it so the body is encoded at the time of sending the message.

              I'm nor sure we need PacketFragment either - can't we just use MessagingBuffer?


              we need somewhere to hold the fragment info, ie packet id, correlation id etc.

              Regarding re-assembling, I'm not sure this is necessary either since when reading several packets off the wire to form a command we can just store the actual buffers, no need to re-assemble?


              we need to reassemble them as we need to know which packet they belong to, and need to wait for all the fragments to arrive before decoding. remember there may be fragments from many packets interleaved in a buffer.

              One thing I noticed is that RemotingServiceImpl and PacketAssemblerImpl have references to a PacketFragmentCache but don't do anything with it.
              This is a holder for WIP.

              • 4. Re: Message Chunking
                timfox

                 

                "ataylor" wrote:

                could do, but i don't think the Packet should care about how messages are broken up.


                I think it's the packet's responsibility to know how to encode itself, whether it encodes itself into one messagingbuffer (normal packet) or many (large message) is behaviour of the packet.


                yes, at the minute they do. this still needs changing. Doing it this way tho' means that every message is still split up into 2 messages since the body is always written before the packet headers etc. I was thinking about changing it so the body is encoded at the time of sending the message.


                For large messages it's important we don't re-encode since that's a lot of copying.
                If the logic for encoding is inside the packet, then it can make the decision at send time whether to just use the message's current buffers as is (for large messages) or re-encode them into another buffer (e.g. small messages).

                Again, this is up to the packet how it wants to encode itself.


                we need somewhere to hold the fragment info, ie packet id, correlation id etc.


                packet id is already written to the buffer, all we need to write is a boolean flag saying "lastPacket", if true then the server knows it's received all fragments. I don't think we need another class to do that, it's just an extra writeBoolean/readBoolean when encoding/decoding.


                we need to reassemble them as we need to know which packet they belong to, and need to wait for all the fragments to arrive before decoding. remember there may be fragments from many packets interleaved in a buffer.


                I don't think that is true. The decoded message can just maintain a list of messagingbuffers and a pointer (int) to a position in the first buffer where the data starts. Different messges can point to the same buffers if there are many messages in the same buffer. I don't think there is any need for re-assembling there.



                • 5. Re: Message Chunking
                  ataylor

                   

                  I think it's the packet's responsibility to know how to encode itself, whether it encodes itself into one messagingbuffer (normal packet) or many (large message) is behaviour of the packet.


                  Ok, i can move this.

                  For large messages it's important we don't re-encode since that's a lot of copying.
                  If the logic for encoding is inside the packet, then it can make the decision at send time whether to just use the message's current buffers as is (for large messages) or re-encode them into another buffer (e.g. small messages).

                  Again, this is up to the packet how it wants to encode itself.


                  ok, again i can change this, I'll add some threshold level, i.e. if body < x add to original buffer.

                  I don't think that is true. The decoded message can just maintain a list of messagingbuffers and a pointer (int) to a position in the first buffer where the data starts. Different messges can point to the same buffers if there are many messages in the same buffer. I don't think there is any need for re-assembling there.


                  I think the point is that we cant decode the message until the last fragment has arrived. so we need to cache these buffers somewhere until we are ready.

                  • 6. Re: Message Chunking
                    timfox

                     

                    "ataylor" wrote:

                    I think the point is that we cant decode the message until the last fragment has arrived. so we need to cache these buffers somewhere until we are ready.


                    Sure, but that doesn't mean they need to be munged (re-assembled) into a single buffer.

                    A message can maintain a list of buffers.

                    • 7. Re: Message Chunking
                      ataylor

                       

                      Sure, but that doesn't mean they need to be munged (re-assembled) into a single buffer.


                      Actually I'm just holding them in a list until ready.

                      Maybe if i move the maintaining of these lists into packet it will make more sense and be simpler?

                      • 8. Re: Message Chunking
                        timfox

                         

                        "ataylor" wrote:
                        Sure, but that doesn't mean they need to be munged (re-assembled) into a single buffer.


                        Actually I'm just holding them in a list until ready.



                        AFAICT from the code you maintain it in the list, but then just call Packet.decode with the list which just copies the whole thing into a single body buffer - so it does get munged.

                        What would be nice is if we could maintain the same buffers in the packet as a list, so no copying.