Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only one active stream even using multiple streams | Head of Line Blocking #125

Closed
qyynuaa opened this issue Jul 20, 2020 · 15 comments
Closed
Labels
bug Something isn't working

Comments

@qyynuaa
Copy link

qyynuaa commented Jul 20, 2020

I'm trying to download multiple resources with multiple streams using http3_client.py and http3_server.py. The purpose is to understand the benefit of avoiding Head of Line Blocking using QUIC.

I run the HTTP3 server:

python3 examples/http3_server.py --certificate tests/ssl_cert.pem --private-key tests/ssl_key.pem

I run the example client to perform four HTTP/3 requests:

python examples/http3_client.py --ca-certs tests/pycacert.pem --quic-log http3 https://localhost:4433/100000 https://localhost:4433/100000 https://localhost:4433/100000 https://localhost:4433/100000 

The result shows that the HTTP requests from the client are sent to the server in parallel, but the server will respond with only one active stream at any time.

image

I think based on QUIC protocol, we can have multiple active streams at the same time, right? I also find an public example from https://qvis.edm.uhasselt.be/#/files --> Option 4 Load a massive demo file.

image

I double checked the source code and I found the current implementation is directly writing all the response body to a byte array, it seems keeps sending the content in this bytearray until it is empty and then switch to start sending another stream.

Did I miss something or are there some configuration parameters I should look at?

Thanks!

@jlaine
Copy link
Contributor

jlaine commented Oct 15, 2020

You are right, the current send loop will drain a stream as much as possible before moving on to the next one.

I had once written a naive patch which shuffled the streams here:

for stream in self._streams.values():

.. however performance took a significant hit. You are welcome to suggest an alternative implementation!

@jlaine
Copy link
Contributor

jlaine commented Mar 9, 2021

Please don't pollute this issue with unrelated matters, open a new issue. I'll let you copy over your text then I'll delete this comment.

@NooshinEghbal
Copy link

Hello,

I got the same results as qyynuaa. Any update on multiplexing?
The strange thing is that in Fig. 1 of "Resource Multiplexing and Prioritization
in HTTP/2 over TCP versus HTTP/3 over QUIC" paper by Robin Marx et al. it seems that aioquic has some sort of multiplexing but qyynuaa and my results do not show that.

@jlaine
Copy link
Contributor

jlaine commented Sep 2, 2021

My comment #125 (comment) still stands, you are welcome to put together a PR for a performant implementation.

@rmarx
Copy link
Contributor

rmarx commented Sep 30, 2021

I've been looking at this for a while now, and I'm thoroughly confused...

I don't have an easy setup to test this at the moment, but using the H3 test from interop.seemann.io, I get this:
https://qvis.quictools.info/#/multiplexing?file=https%3A%2F%2Finterop.seemann.io%2Flogs%2F2021-09-28T08%3A05%2Faioquic_quic-go%2Fhttp3%2Fclient%2Fqlog%2F43efa12aa2437e6fe377c4.qlog

2021-09-30 11_45_48-qvis_ tools and visualizations for QUIC and HTTP_3

That does seem to give more or less sequential sending, with probably an empty send_buffer for yellow somewhere along the middle, and some flushing at the start for the H3 headers maybe?

However, in my original tests, dating from 13 January 2020, I did get -very- clear per-packet multiplexing results for 10 x 1MB files (example file:
run1parallel_10files_1MB_0ms_aioquic.zip

2021-09-30 11_55_02-qvis_ tools and visualizations for QUIC and HTTP_3

I've been looking at the code and can't immediately find major differences in the send loop logic between then and now that would explain this... maybe (probably?) filling the send buffer was done differently then? There's also a difference in how pacing/cwnd adherence is done there, but I don't think that should matter for this...

Maybe @jlaine has an idea of what might have caused my earlier experiments to produce clear multiplexing? I'm personally guessing it has to do with how he put data in the stream send buffers at that time.


Regardless of all this, I strongly feel that the current behaviour (meaning mostly sequential sending of streams) is the best default behaviour, especially when considering Web page loading performance. It's unlikely multiplexing and a bit higher potential HOL-blocking removal would help overall performance much in that typical use case. See also my work into this at https://h3.edm.uhasselt.be/.

@guest271314
Copy link
Contributor

@rmarx What is the canonical procedure to produce an indefinite/infinite datagram or stream from server to client, for example, a live jam session or web radio station? So far I have not successfully achieve that use case myself nor found a solution in the wild.

@rmarx
Copy link
Contributor

rmarx commented Nov 29, 2021

Hey @guest271314,

I am far from an expert in how to program with aioquic... I've mainly used the more top-level APIs to run tests. You'd be better off asking @jlaine as the main implementer here.

Additionally, I don't think your question really has anything to do with the main subject of this issue (as it pertains to how to multiplex different streams, not having a single indefinite stream), so I would recommend you open a new issue for that and provide some more context on what exactly you're trying to do ("an indefinite/infinite datagram or stream" is a very vague description to me).

With best regards,
Robin

@guest271314
Copy link
Contributor

@rmarx I searched for issues as close to my requirements as possible. An indefinite/infinite stream means a web radio station that streams perpetutally; a live musical jam session that could go 2 hours or 2 days; capturing audio and video of a live event without a pre-determined end; etc. I am able to achieve that using Native Messaging with a Python script, and separately, fetch() with PHP passthru(). I have asked the author of this repository previously, I ask again in #242.

@guest271314
Copy link
Contributor

@rmarx FWIW I read the linked tests you performed re QUIC and estimated that you had performed such a live-streaming test. So far I have not located any tests in the wild which address live-streaming using QUIC, specifically with WebTransport. From perspective here that is a use case which needs testing. I am not an expert using Python either. I learned all that Python I use testing WebTransport, thus the question posed to individuals who at least have more experience with QUIC and Python than me. I don't care if one or multiple streams are used, what matters is that the stream is capable of being contigious at the client. Thanks for your reply.

@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@github-actions github-actions bot added the stale label Jul 19, 2022
@jlaine
Copy link
Contributor

jlaine commented Jul 19, 2022

Let's keep this issue active.

@github-actions github-actions bot removed the stale label Jul 20, 2022
@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@Karthikdasari0423
Copy link
Contributor

You are right, the current send loop will drain a stream as much as possible before moving on to the next one.

I had once written a naive patch which shuffled the streams here:

for stream in self._streams.values():

.. however performance took a significant hit. You are welcome to suggest an alternative implementation!

Hi @jlaine

Could you please share that patch here.Some users might not care about performance and will be very intrested on testing with multiple streams

@jlaine jlaine reopened this Jul 4, 2023
@github-actions github-actions bot removed the stale label Jul 5, 2023
Copy link

github-actions bot commented Nov 3, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@github-actions github-actions bot added the stale label Nov 3, 2023
@jlaine jlaine removed the stale label Nov 5, 2023
rthalley added a commit to rthalley/aioquic that referenced this issue Feb 26, 2024
@rthalley rthalley added the bug Something isn't working label Feb 26, 2024
rthalley added a commit to rthalley/aioquic that referenced this issue Feb 27, 2024
@rthalley
Copy link
Contributor

Things should be fairer now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants