Data frames interleaving

75 views
Skip to first unread message

Andrea Cardaci

unread,
Jun 13, 2013, 12:18:06 PM6/13/13
to spdy...@googlegroups.com
Hi folks,
some days ago I opened an issue to node-spdy that I'd like to discuss here (too). For brevity I just link to the original issue since it comes with a number of text dumps.

What I'd like to discuss here is not "why does node-spdy behave this way?" and neither "is this compliant to the spec?" (AFAIK there's nothing in the spec that states that data frames of concurrent streams MUST interleave), but rather I'd like to know whether this data frame interleaving that I'm describing is the desired behavior of SPDY or not. A phrase from the SPDY Best Practices makes me think that the answer is yes:

Use reasonable SPDY frame sizes - Although the spec allows for large frames, it is often desirable to use smaller frames, because this allows for better interleaving of frames from different streams.

Cheers,
Andrea

Hasan Khalil

unread,
Jun 13, 2013, 12:36:04 PM6/13/13
to spdy...@googlegroups.com
Really this is up to the implementor. Flow control and prioritization both play in here, but I think that the SPDY spec should not require interleaving.

    -Hasan


--
 
---
You received this message because you are subscribed to the Google Groups "spdy-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to spdy-dev+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Jamie Hall

unread,
Jun 14, 2013, 5:40:16 AM6/14/13
to spdy...@googlegroups.com
Hi,

Section 2.5 of the SPDY/3 spec says:
Because TCP provides a single stream of data on which SPDY multiplexes multiple logical streams, clients and servers must intelligently interleave data messages for concurrent sessions.

I agree with Hasan that this is entirely up to the implementor. However, good interleaving provides a performance improvement (at worst) and is actually necessary in some cases. If the server only sends frames from one stream before frames from the next, the entire connection will become frozen if one stream pauses for a long time, since no other streams will be able to send. If one stream is taking a long time (maybe it depends on a connection to another server with flaky connectivity, or maybe it's waiting on some event), other streams should be able to send instead.

The Chrome events log you linked to might suggest an implementation issue in node-spdy. My Go implementation of SPDY definitely interleaves packets as necessary, and this has been confirmed in Chrome logs.

Thanks,

Jamie

Andrea Cardaci

unread,
Jun 14, 2013, 6:49:26 AM6/14/13
to spdy...@googlegroups.com
Hi Jamie,
thanks for your response, that's what I wanted to hear.

On Friday, June 14, 2013 11:40:16 AM UTC+2, Jamie Hall wrote:
Hi,

Section 2.5 of the SPDY/3 spec says:
Because TCP provides a single stream of data on which SPDY multiplexes multiple logical streams, clients and servers must intelligently interleave data messages for concurrent sessions.

Ah, true! I even read that...
 
I agree with Hasan that this is entirely up to the implementor. However, good interleaving provides a performance improvement (at worst) and is actually necessary in some cases. If the server only sends frames from one stream before frames from the next, the entire connection will become frozen if one stream pauses for a long time, since no other streams will be able to send. If one stream is taking a long time (maybe it depends on a connection to another server with flaky connectivity, or maybe it's waiting on some event), other streams should be able to send instead.

Agree, with a behavior like the one I described will be little or no improvement compared to HTTP pipelining over one socket. I must say though that my test is far from being complete, I mean it's just one test case... I'll wait an answer to the issue for that.

Tatsuhiro Tsujikawa

unread,
Jun 15, 2013, 8:30:25 AM6/15/13
to spdy...@googlegroups.com
Hi,

We encountered same interleaving issue in spdylay development:

The problem appears especially on between fast and long stream with higher priority and lower priority streams (e.g., images). For example, imagine downloading data with high priority while browsing web pages. If a web page contains images, (since chrome requests image with lower priority), image transfer starves. In spdylay, we chunked DATA frame at most 4K but it still does not help.
Just interleaving everything will make priority useless. So we need some cleverness to make interleaving while adhering priority. In spdylay, we do a simple workaround which gives more change to output data to lower priority stream and at the same time still honoring priority. Still it is not as smooth as separate connections with legacy HTTP/1.1.

Best regards,

Tatsuhiro Tsujikawa



--

Jamie Hall

unread,
Jun 15, 2013, 8:53:32 AM6/15/13
to spdy...@googlegroups.com
For what it's worth, my SPDY library uses Go's channels to perform interleaving with priority. It has one channel per priority, and uses a separate Goroutine to perform sending. This sending goroutine checks for any frames in the priority 0 channel, then checks priority 1, and so on until all channels have been checked. If it finds a frame in any channel, that frame is sent and the process begins again. If no frames are found in any channel, then all channels are listened to, so the next frame put in any channel will be sent, irrespective of priority, since it will be the only available frame.

This means that frames of higher priority will always be sent before frames of lower priority, but that frames are otherwise sent as soon as possible, in the order in which they're placed in an output channel. Since the sending goroutine is unaware of streams, interleaving will occur naturally.

I apologise for the poor description, but I thought it might be useful to explain how my library performs the interleaving.

Patrick McManus

unread,
Jun 15, 2013, 9:37:06 AM6/15/13
to spdy...@googlegroups.com
I would argue that spdy prioritization is a massive improvement over paralleiization in http/1. in http/1 low priority content regularly chokes out high priority content - its so severe that browsers sometimes serializes low requests completely behind high ones to avoid this.

The keys to a successful muxing in my experience:
 * small frame sizes so you can quickly make priority adjustments
 * any send buffer beyond the frame you are working on should be eliminated so you can quickly make priority adjustments. that's both in your spdy code, the OS kernel buffers, and in any framework you're building spdy on top of..
 * heavily weighted priority queueing..(I don't lke strict priority queues because they can completely starve things too easily)

I think the jury is still out on whether or not you should interleave 2 streams of the same priority. There are uses cases for various approaches.

The big thing that plays havoc with this is the presence of other buffers in the network.. but they do strange things to your parallel http/1 streams too.
Reply all
Reply to author
Forward
0 new messages