cloudflare / quiche

šŸ„§ Savoury implementation of the QUIC transport protocol and HTTP/3

Home Page:https://docs.quic.tech/quiche/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

When should `h3::Connection.poll` be called?

opened this issue Ā· comments

Obviously, when h3::Connection.poll returns Done, we need to wait for something to happen and then call it again. The question is, what exactly do we need to wait for?

poll() processes received transport layer stream data, so the ideal time to call it is after receiving a flight of QUIC packets e.g. reading a batch of UDP datagrams and then processing them with quiche::connection::recv

I am writing a thin wrapper with the goal of running quiche on any single-threaded async executor. The async logic in Rust is essentially about polling until blocked, then registering a waker to be awakened when it can be polled again. This is very similar to the event loop model in quiche. To make this wrapper work properly, I need to know when to poll it again for any function that can possibly return Done.

I've answered the original question, not really sure what more you're looking for.

The timeout logic in the example code is quite confusing. It seems to be performing both a timeout and receiving UDP packets simultaneously. If the timeout expires, the receiving is canceled, and if data is received, the timeout is canceled. This is a strange logic. My question is: When should the timeout function be called to fetch the timeout duration, and if a data packet is received during this period, should the future on_timeout call be canceled to fetch the timeout duration again?

APIs like send_response and send_body may not be able to complete temporarily and will need to be retried in the future. My question is really simple: for this type of API that may not be able to complete now, when should I call them again?

I've answered the original question, not really sure what more you're looking for.

This also includes APIs like is_established and is_closed. I'm waiting for is_established to be true because I want to open an HTTP3 connection. If I call is_established and get false, when should I call it again?
@LPardue

Connection.send has detailed documentation, but I believe every function based on polling needs documentation explaining when the result may change and when it can be polled again.

The general principle is that the transport layer always needs to be driven with regularity. Receiving packets will update internal quiche state, so really that is the ideal time to try any APIs that would insert into/pull from the transport layer, or expose information such as is_established.

Timeout values are updated internally and are likely to be recalculated when packets are received. On_timeout does nothing if it is called too early. Its more optimal to cancel and recreate a timeout tiner but nothing bad would happen it multiple were to fire (caveat that on_timeout does need to be called, ideally as soon as it expires).

My idea is to minimize the chances of not making progress when re-polling the API, but based on your description, it seems like everything needs to be re-polled when recv is invoked?

The general principle is that the transport layer always needs to be driven with regularity. Receiving packets will update internal quiche state, so really that is the ideal time to try any APIs that would insert into/pull from the transport layer, or expose information such as is_established.

Timeout values are updated internally and are likely to be recalculated when packets are received. On_timeout does nothing if it is called too early. Its more optimal to cancel and recreate a timeout tiner but nothing bad would happen it multiple were to fire (caveat that on_timeout does need to be called, ideally as soon as it expires).