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

Enable reuse_port(true) in easy way #219

Closed
michael-a-cliqz opened this issue Jan 7, 2020 · 5 comments
Closed

Enable reuse_port(true) in easy way #219

michael-a-cliqz opened this issue Jan 7, 2020 · 5 comments

Comments

@michael-a-cliqz
Copy link
Contributor

Feature Request

Crates

tonic

Motivation

We are trying to build multithreaded server, where each thread is supposed to run following code snippet:

    tokio::runtime::Runtime::new().unwrap().block_on(async {
        tonic::transport::Server::builder().add_service(...).serve(address).await;
    });

But as long as all our threads share same address, it doesn't work.
Now this could be done by using net2::TcpBuilder::reuse_port(true) and then passing produced listener to Server::builder()::serve_with_incoming(), just like uds example does.
Unfortunately, this approach is too tedious for controlling single socket option. It would be nice to have some friendly interface instead.

@LucioFranco
Copy link
Member

I don't think this is a supported feature in hyper currently, so I think if we want this to be added to tonic::transport then I think that would be the right path to go down. Aka we should probably open an issue in hyper about this.

May I ask what is tedious about using the method that is in the uds example?

@michael-a-cliqz
Copy link
Contributor Author

we should probably open an issue in hyper about this.

Fair enough, will do it

May I ask what is tedious about using the method that is in the '''uds''' example?

If I got it correctly, we need to implement AsyncRead, AsyncWrite ourselves. Although, what we really want is to customize listener, and not the stream.

@LucioFranco
Copy link
Member

So you can use tokio's tcp stream type which implements those traits. I would suggest using the tokio tcplistener, and set the options you want. https://docs.rs/tokio/0.2.8/tokio/net/struct.TcpListener.html#method.incoming this should then create a stream of tcpstreams that should align with the incoming types for tonic.

@michael-a-cliqz
Copy link
Contributor Author

So you can use tokio's tcp stream type which implements those traits. I would suggest using the tokio tcplistener, and set the options you want. https://docs.rs/tokio/0.2.8/tokio/net/struct.TcpListener.html#method.incoming this should then create a stream of tcpstreams that should align with the incoming types for tonic.

Right, thats what I am basically doing. But also what I need to do is to add a new datatype:

struct MyStream(tokio::net::TcpStream);

impl Connected for MyStream {}

impl AsyncRead for MyStream {
    fn poll_read(
        mut self: Pin<&mut Self>,
        cx: &mut Context<'_>,
        buf: &mut [u8],
    ) -> Poll<std::io::Result<usize>> {
        Pin::new(&mut self.0).poll_read(cx, buf)
    }
}

impl AsyncWrite for MyStream {
    fn poll_write(
        mut self: Pin<&mut Self>,
        cx: &mut Context<'_>,
        buf: &[u8],
    ) -> Poll<std::io::Result<usize>> {
        Pin::new(&mut self.0).poll_write(cx, buf)
    }

    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
        Pin::new(&mut self.0).poll_flush(cx)
    }

    fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
        Pin::new(&mut self.0).poll_shutdown(cx)
    }
}

So I am just duplicating code from uds example.
Is there any easier solution?

@LucioFranco
Copy link
Member

@michael-a-cliqz there is, I forgot to add a impl for Connected for tokoo::net::TcpStream. I only have it for hyper::server::conn::AddrStream :)

I'd accept a PR that does this for TcpStream https://github.com/hyperium/tonic/blob/master/tonic/src/transport/server/conn.rs#L24

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants