-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Waiting for HUP on TCP socket #3467
Comments
The Tokio type internally uses @Thomasdezeeuw Does the various OSes even provide such an interest? |
This related discussion shows that it seems to be impossible to build a HUP-propagating TCP forwarder with just Tokio (but possible lower-level and less portable |
Sorry I never received this notification, or I missed the email. As far as I've also answered here tokio-rs/mio#1476, but Tokio should be getting |
@benesch looking at your example I have a question; do you read from the connection? Because if so the easiest way to detect a broken/closed connection is by reading and getting zero bytes. This indicates the connection is closed, or the other side called |
Indeed, it'd be swell if we could read from the connection to determine if the client had gone away. But the protocol we're implementing (the PostgreSQL |
I'm not sure how much sense that last comment made. Let me try again with code. You might hope to be able to write: fn write_stream(conn: TcpStream, stream: &dyn Stream<Item = Vec<u8>>) -> Result<(), &'static str> {
loop {
select! {
msg = stream.next() => match msg {
None => return Ok(()),
Some(data) => conn.write_all(data).await,
}
res = conn.read(&mut [0; 1]) => match res {
Ok(1) => {
// Gotta stick this byte somewhere... plus if we saw one
// byte we're probably going to see a lot more, but that
// doesn't mean we can stop sending the data from `stream`
// to the client.
}
Ok(0) => {
// Client went away. Give up.
return Ok(())
}
Err(e) => return Err("conn broke"),
}
}
}
} The problem, as described in the comment within, is what happens when you read and get actual bytes back. If you get a short read you're golden because you know the client has gone away, and you can give up. But if you see bytes... well, you gotta buffer those bytes somewhere. And ideally you'd leave them in the kernel buffer for later, because that way eventually you'll apply some backpressure on the client that's writing a lot of bytes that you don't want to see yet. |
|
@benesch, The socket may be half-closed: the client had finished writing to it and called |
That's not a thing that our clients do! But agree that it would be useful to support for other folks that do use half closed sockets. |
Aha. Well if it is possible to detect it, it would be good to provide a way to do so. |
Any progress here? |
We added something called error interest, which you can wait for. Not sure if it is helpful in this case. |
Can that error interest be used to implement something like |
I’ve found waiting on priority interest works if you’re using Linux. |
This is a resubmission of #483 for the Tokio v1.0 era. The question is thus: "how do I wait for a TCP socket to close without reading from or writing to that socket?"
First, some quick history! #483 was resolved with this suggestion:
But
poll_read_ready
was later removed, so 6d8cc4e was filed asking about how to wait for HUP withoutpoll_read_ready
. The proposed solution was to restorepoll_read_ready
. That method is now restored (#2968), but it's no longer clear to me how one uses it to wait for just HUP. In Tokio v1.0, there is noReady::hup()
.Here's the comment I posted on #2968, which contains my current hacky attempt to wait for HUP, and my ideal API:
The text was updated successfully, but these errors were encountered: