-
Notifications
You must be signed in to change notification settings - Fork 51
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
Client initiated drain #436
Comments
It might be helpful to have a concrete use case that cannot be satisfied by the existing API. Within the existing API, the client can stop accepting incoming undirectional or bidirectional steams, while continuing to read from streams that were previously accepted. In the IETF issue, there is a question about whether a drain request implies that the server should stop sending datagrams or just stop creating "new work" (however, the server defines that). It is also possible for an application to define its own messages. For example, an RTP over WebTransport implementation could use the |
With the existing API, the client can stop accepting incoming streams. However it cannot stop the server from sending data across existing streams. The client can close() the existing streams of course, but then it risks losing data in flight. |
This sounds like a "graceful shutdown" use case, where the client is asking the server to finish the existing work but not initiate new work, so that the client can take care of the data in flight (e.g. write it to stable storage) and then close the session. It does lead me to wonder how quickly the server is expected to wrap things up. Should the server stop sending immediately, or can it continue to a logical break point (e.g. finish sending the current video, but don't keep sending more videos after that)? |
The IETF definition is intentionally vague on the timing question, with a SHOULD to "gracefully terminate the session as quickly as possible".
We could use similar language and guidance if we do want to implement a drain() method. |
I think a lot of this is likely going to be application or deployment specific. So staying vague, or giving non-exhaustive examples, is the appropriate way to phrase it. While rejecting new things is always possible. Draining helps both sides avoid pointless work. And as per the IETF issue ietf-wg-webtrans/draft-ietf-webtrans-http3#27 it can be used by intermediaries that are not application aware if they have operational needs. |
@vasilvv Do you have an opinion on this? |
Meeting:
|
At IETF 116, WebTransport meeting, room feedback was to allow client initiated drain. |
Some questions:
|
We only handle incoming DRAIN capsule once, so it would make to send one only once. We could make it return a promise, but I am not sure what users would do with it.
Idempotent should have better ergonomics.
Unlike HTTP, we don't really alter connection behavior upon draining signal, so I'm not sure that's necessary.
HTTP does that. I think we should avoid that, since that makes some assumptions about how the application works that are not necessary. |
This seems like something that would be nice but not necessary, but It exists in IETF so we should probably expose it. |
If DRAIN is only sent once, what guarantee is there that the server received it? |
Meeting:
|
Based on #436 (comment) and "either endpoint can send a DRAIN_WEBTRANSPORT_SESSION capsule" the likely API need here is something like: wt.drain(); // void, no promise
await wt.draining; // will resolve in the next task
// we are now in "draining" state. ...probably with something like:
@nidhijaju do you have cycles to add something like this? Or we can reassign. |
It feels weird that we don't block new stream creation upon If we mean the actual website itself, why can't it just send its own message to signal draining, i.e. why specify a capsule/API at all? |
IMHO, "application" refers to both the client's Javascript application as well as server-side code, for either the server -> client or client -> server cases.
The application can send its own message, so it's a good question. The stream that the message would be sent over will differ but does that make much difference? Perhaps this is about convenience, saving the JS client application from needing to write their own drain() method, and allowing a node application to react to receipt of DRAIN_WEBTRANSPORT_SESSION ? |
I'm with @ekinnear here. HTTP has a GOAWAY frame because HTTP is an application protocol and people use HTTP directly. However, we didn't add that capability to QUIC, so why would we add it here? (CONNECTION_CLOSE is not a graceful shutdown mechanism, it's an abrupt termination signaling mechanism, for error conditions.) That line of thinking is making me less than enthusiastic about DRAIN_WEBTRANSPORT_SESSION. If the intermediate stack layers (the browser) can't act on the signal in a meaningful way, then it's not a useful signal at that layer. |
Meeting:
|
As noted in #432 , per IETF a client may send a DRAIN_WEBTRANSPORT_SESSION signal to a server, to indicate that the server SHOULD NOT initiate new WebTransport streams or datagram flows.
Do we need a wt.drain() method to initiate this signal?
Would write() and stream creation methods work after drain() has been called?
The text was updated successfully, but these errors were encountered: