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

Make TcpIncoming public #1037

Merged
merged 5 commits into from Jul 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
54 changes: 52 additions & 2 deletions tonic/src/transport/server/incoming.rs
Expand Up @@ -127,12 +127,48 @@ enum SelectOutput<A> {
Done,
}

pub(crate) struct TcpIncoming {
/// Binds a socket address for a [Router](super::Router)
///
/// An incoming stream, usable with [Router::serve_with_incoming](super::Router::serve_with_incoming),
/// of `AsyncRead + AsyncWrite` that communicate with clients that connect to a socket address.
#[derive(Debug)]
pub struct TcpIncoming {
inner: AddrIncoming,
}

impl TcpIncoming {
pub(crate) fn new(
/// Creates an instance by binding (opening) the specified socket address
/// to which the specified TCP 'nodelay' and 'keepalive' parameters are applied.
/// Returns a TcpIncoming if the socket address was successfully bound.
///
/// # Examples
/// ```no_run
/// # use tower_service::Service;
/// # use http::{request::Request, response::Response};
/// # use tonic::{body::BoxBody, transport::{Body, NamedService, Server, server::TcpIncoming}};
/// # use core::convert::Infallible;
/// # use std::error::Error;
/// # fn main() { } // Cannot have type parameters, hence instead define:
/// # fn run<S>(some_service: S) -> Result<(), Box<dyn Error + Send + Sync>>
/// # where
/// # S: Service<Request<Body>, Response = Response<BoxBody>, Error = Infallible> + NamedService + Clone + Send + 'static,
/// # S::Future: Send + 'static,
/// # {
/// // Find a free port
/// let mut port = 1322;
/// let tinc = loop {
/// let addr = format!("127.0.0.1:{}", port).parse().unwrap();
/// match TcpIncoming::new(addr, true, None) {
/// Ok(t) => break t,
/// Err(_) => port += 1
/// }
/// };
/// Server::builder()
/// .add_service(some_service)
/// .serve_with_incoming(tinc);
/// # Ok(())
/// # }
pub fn new(
addr: SocketAddr,
nodelay: bool,
keepalive: Option<Duration>,
Expand All @@ -151,3 +187,17 @@ impl Stream for TcpIncoming {
Pin::new(&mut self.inner).poll_accept(cx)
}
}

#[cfg(test)]
mod tests {
use crate::transport::server::TcpIncoming;
#[tokio::test]
async fn one_tcpincoming_at_a_time() {
let addr = "127.0.0.1:1322".parse().unwrap();
{
let _t1 = TcpIncoming::new(addr, true, None).unwrap();
let _t2 = TcpIncoming::new(addr, true, None).unwrap_err();
}
let _t3 = TcpIncoming::new(addr, true, None).unwrap();
}
}
2 changes: 1 addition & 1 deletion tonic/src/transport/server/mod.rs
Expand Up @@ -24,7 +24,7 @@ use super::service::TlsAcceptor;
#[cfg(unix)]
pub use unix::UdsConnectInfo;

use incoming::TcpIncoming;
pub use incoming::TcpIncoming;

#[cfg(feature = "tls")]
pub(crate) use tokio_rustls::server::TlsStream;
Expand Down