Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Enable reuse_port(true) in easy way #219

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

Enable reuse_port(true) in easy way #219

michael-a-cliqz opened this issue Jan 7, 2020 · 6 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

@alidehghan
Copy link

could you please provide a gist to use Socket2 and reuse_port?

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

No branches or pull requests

3 participants