Subject: [hybi] Multiplexing: Efficiency of multiple multiplex controls in one WebSocket message

From: Takeshi Yoshino <[email-masked]>
Date: Thu, 5 Apr 2012 18:12:07 +0900

Hi,

Current multiplexing spec allows putting multiple multiplex control blocks
in one WebSocket message. Maybe this is optimization to reduce overhead
(WebSocket header (2-10 octet), masking (4 octet, only C->S direction) and
channel ID of 0 (1 octet)) by merging multiple multiplex controls into one
message (especially for FlowControl which is exchanged frequently). Right,
John?

(multiplex control is not user data, so we don't have to give different
masks for each of them)

To allow multiple blocks, this optimization introduced one more framing
mechanism (we already have two (payload, channel ID)) and 1-4 octet
overhead inside. 6 octet/control overhead reduction looks beneficial.
However having three non-trivial length encodings sounds not so good.

Should we
1) just map one multiplex control to one message
or at least
2) reuse either payload encoding or channel ID encoding for length of
additional data?

I don't have strong objection to current spec. I want to check if it's ok
before we proceed.

Thanks
Takeshi

---

From: John Tamplin <[email-masked]>
Date: Thu, 5 Apr 2012 05:20:57 -0400

> message (especially for FlowControl which is exchanged frequently). Right,

Yes, the idea was that flow control messages, in particular, will be very
frequent so we need to aggregate them to have acceptable efficiency.

-- 
John A. Tamplin
Software Engineer (GWT), Google

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 12 Apr 2012 09:28:37 +1000

Note that I think the nature of sending flow control messages is that
there will be little opportunity to aggregate them into a single
message while sending.  Typically a flow control message will be sent
as some channel specific buffer it consumed below some threshhold.
It may then be more work (and latency) to attempt to build a queue of
such control messages in order to be able to send them as a single
message - it is probably simpler to just immediately frame them and
add them to the byte buffer that is being flushed.

So my hunch is that we will mostly end up sending a single control
frame per message. However, I don't see too much complexity or
problems in allowing them to be batched into a single message, so I
think it is low cost for a possible low gain.

But to be really clear, the current draft says:

   Binary frames with a channel ID of 0 contain zero or more multiplex
   control blocks in "Payload data".

This is written in terms of frames rather than messages.    Does this
mean we can assume that a channel ID 0 frame will never be fragmented,
even by intermediaries?     It would certainly make it easier to
handle if they were restricted to frames, as control blocks would not
be split over multiple frames - but I'm not sure we can guarantee
this?  what if we had 100,000 flow control ops in a single frame -
would intermediaries be prevented from fragmenting that?    If they
did fragment, they would have to put channelIDs into the fragments,
but would we also insist that they break the frames on control block
boundaries?

cheers

On 5 April 2012 19:20, John Tamplin <[email-masked]> wrote:
> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi
>

---

From: Takeshi Yoshino <[email-masked]>
Date: Thu, 12 Apr 2012 18:34:43 +0900

On Thu, Apr 12, 2012 at 08:28, Greg Wilkins <[email-masked]> wrote:
<snip>

> think it is low cost for a possible low gain.

Thanks for your opinion.

I think we should avoid the 1 extra octet overhead if it's estimated to be
really rare that we get a chance to merge multiple FlowControls into one
message.

> This is written in terms of frames rather than messages.    Does this

Good point. I left this part unclear by mistake.

I didn't intend to mean that channel 0 messages MUST NOT be fragmented at a
point in the middle of a control block by this text. This point is open for
discussion.

> but would we also insist that they break the frames on control block

I thought it's fine that a control block may be split into two or more
fragments. As far as control blocks are sent in-order (relative to both
other control blocks and data of multiplexed channels), it's not a problem.

I don't see significant advantage from neither of them. Prohibition of
fragmentation might make message processing easier as you said above, but
adding constraints to care should be avoided unless we really
need basically.
(Maybe this is Patrick's original suggestion which made control frame
unfragmentable and limited its length up to 125
http://trac.tools.ietf.org/wg/hybi/trac/ticket/19#comment:1)

Rather I think we should add a text to say that fragments of a channel ID 0
message MUST NOT be interleaved with other channels. Such operation makes
it unclear at which point (of stream of the objective channel) the
operation should be applied.

---

From: Greg Wilkins <[email-masked]>
Date: Fri, 13 Apr 2012 09:00:52 +1000

On 12 April 2012 19:34, Takeshi Yoshino <[email-masked]> wrote:
> unfragmentable and limited its length up to
> 125 http://trac.tools.ietf.org/wg/hybi/trac/ticket/19#comment:1)
>
> message MUST NOT be interleaved with other channels. Such operation makes it
> unclear at which point (of stream of the objective channel) the operation
> should be applied.

Takeshi,

I think to constrain channel 0 fragments to be not interleaved is just
as hard (if not harder) than saying they can't be fragmented and it
still represents adding a constraint either way.

So I believe we should strive to allow entirely normal fragmentation
of channel 0 messages, thus avoiding any constraint.  If we have to
have a constraint, then I'd prefer no fragmentation or fragmentation
on block boundaries rather than a restriction on interleaving.

The problem with normal fragmentation of channel0, is as you say, to
determine when an operation should be applied.  Is there a problem
with saying that the operations within a channel 0 message will only
be applied once the entire message is received?   As I've said
previously, I think it highly unlikely that we will have many blocks
in the same message, so I think fragmentation is unlikely to
occur..... but if it did, are there any bad consequences of delaying
processing?

I note that the current draft says in 7.5

   Multiplex control blocks are sent in data frames, so they can be
   fragmented.  Processing of a multiplex control block MAY be done once
   the block is received completely without waiting for the whole binary
   message is received (and becomes available after decoding if any).

Which say they MAY be processed as they are completely received,
suggesting that there is no MUST about processing them immediately - I
certainly can't think of a reason.   So perhaps this is the most
flexible way - obviously blocks MUST be processed when the entire
message is received, but MAY be processed as each frame is decoded.
I can't see any problems with early processing either.   I guess my
only concern is that it would allow different behaviour which might
allow for future complications, so I'd be OK with enforcing either
early or later processing of the blocks.

Note also that 7.5 only applies to encapsulated control frames - so
perhaps this text needs to be applied to all block types?

cheers

---

From: Takeshi Yoshino <[email-masked]>
Date: Fri, 13 Apr 2012 14:28:10 +0900

> still represents adding a constraint either way.

I just thought it might be better to keep fragmentation available but it's
totally useless to allow interleaving between 0 and non-zero channel. OK,
I'm fine with your idea.

> occur..... but if it did, are there any bad consequences of delaying

Agreed. If control blocks in the same message are split into fragments, the
benefit of multiple-blocks-in-a-message is already lost because overhead
(see my first post for detail) is added on fragmentation. If the sender is
really concerned with such delay, it can just use two messages and put such
blocks in the first message instead of fragmentation.

> message is received, but MAY be processed as each frame is decoded.

Yes, that's what I meant.

> early or later processing of the blocks.

Let's just take your proposal
"the operations within a channel 0 message will only be applied once the
entire message is received"
Now I don't see any problem with this simplest one.

> perhaps this text needs to be applied to all block types?

Yes!

Thanks.