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

net: add function for listening to socket readiness events #2968

Closed
carllerche opened this issue Oct 16, 2020 · 4 comments
Closed

net: add function for listening to socket readiness events #2968

carllerche opened this issue Oct 16, 2020 · 4 comments
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. C-proposal Category: a proposal and request for comments E-help-wanted Call for participation: Help is requested to fix this issue. M-net Module: tokio/net

Comments

@carllerche
Copy link
Member

carllerche commented Oct 16, 2020

TcpStream, TcpListener, UdpSocket, ... should provide async functions for receiving readiness events.

Something like:

async fn ready(interest: ???) -> io::Result<???>;

This would allow the user to hook into arbitrary readiness events and receive notifications such as HUP.

We also should provide poll_ready_ready and poll_write_ready for each socket type.

Open question

Should the ready function return a ReadyGuard similar to AsyncFd or should it clear readiness in the try_read / try_write function?

Refs: #2903

@carllerche carllerche added C-proposal Category: a proposal and request for comments A-tokio Area: The main tokio crate M-net Module: tokio/net C-feature-request Category: A feature request. labels Oct 16, 2020
@benesch
Copy link
Contributor

benesch commented Jan 8, 2021

It's still not entirely clear to me whether it's possible to use this API to wait for just HUP. I managed to get something working here, but it's suboptimal: MaterializeInc/materialize#5235

The tl;dr is what you have to write currently is something like this, which polls Interest::READABLE and then inspects whether the resulting Ready indicates is_read_closed:

fn write_stream(conn: TcpStream, stream: &dyn Stream<Item = Vec<u8>>) -> Result<(), &'static str> {
    loop {
        match time::timeout(Duration::from_secs(1), stream.next()).await {
            Ok(None) => return Ok(()),
            Ok(Some(data)) => conn.write_all(data).await,
            Err(_) => {
                let ready = conn.ready(Interest::READABLE).await?;
                if ready.is_read_closed() {
                    return Err("conn broke");
                }
            }
        }
    }
}

But ideally you'd be able to block on the READ_CLOSED event directly, or something:

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,
            }
            _ = conn.ready(Interest::READ_CLOSED) => return Err("conn broke"),
        }
    }
}

@benesch
Copy link
Contributor

benesch commented Jan 8, 2021

Oh, by the way, #3246 merged, so I think technically this issue is complete. I can file a new issue for the HUP thing, if you prefer.

@Darksonn
Copy link
Contributor

Darksonn commented Jan 8, 2021

Yeah, please file a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. C-proposal Category: a proposal and request for comments E-help-wanted Call for participation: Help is requested to fix this issue. M-net Module: tokio/net
Projects
None yet
Development

No branches or pull requests

3 participants