Skip to content

Commit

Permalink
Quick and dirty patch to compile client-only transport on wasm32.
Browse files Browse the repository at this point in the history
  • Loading branch information
boxdot committed Nov 12, 2020
1 parent ed7a686 commit b06a97d
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 32 deletions.
16 changes: 14 additions & 2 deletions tonic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ keywords = ["rpc", "grpc", "async", "futures", "protobuf"]
default = ["transport", "codegen", "prost"]
codegen = ["async-trait"]
transport = [
"hyper/default",
"hyper/stream",
"tokio",
"tower",
"tower-balance",
"tower-load",
"tracing-futures",
]
client = [
"hyper",
"tokio",
"tower",
Expand Down Expand Up @@ -64,8 +73,8 @@ prost-derive = { version = "0.6", optional = true }
async-trait = { version = "0.1.13", optional = true }

# transport
hyper = { version = "0.13.4", features = ["stream"], optional = true }
tokio = { version = "0.2.13", features = ["tcp"], optional = true }
hyper = { version = "0.13.4", default-features = false, optional = true }
tokio = { version = "0.2.13", optional = true }
tower = { version = "0.3", optional = true}
tower-make = { version = "0.3", features = ["connect"] }
tower-balance = { version = "0.3", optional = true }
Expand All @@ -76,6 +85,9 @@ tracing-futures = { version = "0.2", optional = true }
tokio-rustls = { version = "0.14", optional = true }
rustls-native-certs = { version = "0.4", optional = true }

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen-futures = "0.4.18"

[dev-dependencies]
tokio = { version = "0.2", features = ["rt-core", "macros"] }
static_assertions = "1.0"
Expand Down
2 changes: 1 addition & 1 deletion tonic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub mod codec;
pub mod metadata;
pub mod server;

#[cfg(feature = "transport")]
#[cfg(any(feature = "transport", feature = "client"))]
#[cfg_attr(docsrs, doc(cfg(feature = "transport")))]
pub mod transport;

Expand Down
6 changes: 3 additions & 3 deletions tonic/src/request.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::metadata::MetadataMap;
#[cfg(feature = "transport")]
#[cfg(any(feature = "transport", feature = "client"))]
use crate::transport::Certificate;
use futures_core::Stream;
use http::Extensions;
use std::net::SocketAddr;
#[cfg(feature = "transport")]
#[cfg(any(feature = "transport", feature = "client"))]
use std::sync::Arc;

/// A gRPC request and metadata from an RPC call.
Expand All @@ -18,7 +18,7 @@ pub struct Request<T> {
#[derive(Clone)]
pub(crate) struct ConnectionInfo {
pub(crate) remote_addr: Option<SocketAddr>,
#[cfg(feature = "transport")]
#[cfg(any(feature = "transport", feature = "client"))]
pub(crate) peer_certs: Option<Arc<Vec<Certificate>>>,
}

Expand Down
3 changes: 3 additions & 0 deletions tonic/src/transport/channel/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ impl Endpoint {
// FIXME: determine if we want to expose this or not. This is really
// just used in codegen for a shortcut.
#[doc(hidden)]
#[cfg(feature = "transport")]
pub fn new<D>(dst: D) -> Result<Self, Error>
where
D: TryInto<Self>,
Expand Down Expand Up @@ -203,6 +204,7 @@ impl Endpoint {
}

/// Create a channel from this config.
#[cfg(feature = "transport")]
pub async fn connect(&self) -> Result<Channel, Error> {
let mut http = hyper::client::connect::HttpConnector::new();
http.enforce_http(false);
Expand All @@ -223,6 +225,7 @@ impl Endpoint {
///
/// The channel returned by this method does not attempt to connect to the endpoint until first
/// use.
#[cfg(feature = "transport")]
pub fn connect_lazy(&self) -> Result<Channel, Error> {
let mut http = hyper::client::connect::HttpConnector::new();
http.enforce_http(false);
Expand Down
2 changes: 2 additions & 0 deletions tonic/src/transport/channel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ impl Channel {
///
/// This creates a [`Channel`] that will load balance accross all the
/// provided endpoints.
#[cfg(feature = "transport")]
pub fn balance_list(list: impl Iterator<Item = Endpoint>) -> Self {
let (channel, mut tx) = Self::balance_channel(DEFAULT_BUFFER_SIZE);
list.for_each(|endpoint| {
Expand All @@ -121,6 +122,7 @@ impl Channel {
/// Balance a list of [`Endpoint`]'s.
///
/// This creates a [`Channel`] that will listen to a stream of change events and will add or remove provided endpoints.
#[cfg(feature = "transport")]
pub fn balance_channel<K>(capacity: usize) -> (Self, Sender<Change<K, Endpoint>>)
where
K: Hash + Eq + Send + Clone + 'static,
Expand Down
20 changes: 20 additions & 0 deletions tonic/src/transport/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,34 @@
//! [rustls]: https://docs.rs/rustls/0.16.0/rustls/

pub mod channel;
#[cfg(feature = "transport")]
pub mod server;

/// Trait that connected IO resources implement.
///
/// The goal for this trait is to allow users to implement
/// custom IO types that can still provide the same connection
/// metadata.
pub trait Connected {
/// Return the remote address this IO resource is connected too.
fn remote_addr(&self) -> Option<std::net::SocketAddr> {
None
}

/// Return the set of connected peer TLS certificates.
fn peer_certs(&self) -> Option<Vec<Certificate>> {
None
}
}

mod error;
mod service;
mod tls;

#[doc(inline)]
pub use self::channel::{Channel, Endpoint};
pub use self::error::Error;
#[cfg(feature = "transport")]
#[doc(inline)]
pub use self::server::{NamedService, Server};
pub use self::tls::{Certificate, Identity};
Expand All @@ -105,5 +124,6 @@ pub use hyper::{Body, Uri};
#[cfg_attr(docsrs, doc(cfg(feature = "tls")))]
pub use self::channel::ClientTlsConfig;
#[cfg(feature = "tls")]
#[cfg(feature = "transport")]
#[cfg_attr(docsrs, doc(cfg(feature = "tls")))]
pub use self::server::ServerTlsConfig;
19 changes: 1 addition & 18 deletions tonic/src/transport/server/conn.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,12 @@
use super::super::Connected;
#[cfg(feature = "tls")]
use super::TlsStream;
use crate::transport::Certificate;
use hyper::server::conn::AddrStream;
use std::net::SocketAddr;
use tokio::net::TcpStream;
#[cfg(feature = "tls")]
use tokio_rustls::rustls::Session;

/// Trait that connected IO resources implement.
///
/// The goal for this trait is to allow users to implement
/// custom IO types that can still provide the same connection
/// metadata.
pub trait Connected {
/// Return the remote address this IO resource is connected too.
fn remote_addr(&self) -> Option<SocketAddr> {
None
}

/// Return the set of connected peer TLS certificates.
fn peer_certs(&self) -> Option<Vec<Certificate>> {
None
}
}

impl Connected for AddrStream {
fn remote_addr(&self) -> Option<SocketAddr> {
Some(self.remote_addr())
Expand Down
2 changes: 1 addition & 1 deletion tonic/src/transport/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod incoming;
#[cfg_attr(docsrs, doc(cfg(feature = "tls")))]
mod tls;

pub use conn::Connected;
pub use super::Connected;
#[cfg(feature = "tls")]
pub use tls::ServerTlsConfig;

Expand Down
33 changes: 27 additions & 6 deletions tonic/src/transport/service/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ pub(crate) struct Connection {
inner: BoxService<Request, Response, crate::Error>,
}

#[cfg(target_arch = "wasm32")]
mod wasm {
use std::future::Future;
use std::pin::Pin;

type BoxSendFuture = Pin<Box<dyn Future<Output = ()> + Send>>;

pub struct Executor;

impl hyper::rt::Executor<BoxSendFuture> for Executor {
fn execute(&self, fut: BoxSendFuture) {
wasm_bindgen_futures::spawn_local(fut)
}
}
}

impl Connection {
pub(crate) fn new<C>(
connector: C,
Expand All @@ -44,16 +60,21 @@ impl Connection {
.http2_initial_stream_window_size(endpoint.init_stream_window_size)
.http2_initial_connection_window_size(endpoint.init_connection_window_size)
.http2_only(true)
.http2_keep_alive_interval(endpoint.http2_keep_alive_interval)
// .http2_keep_alive_interval(endpoint.http2_keep_alive_interval)
.clone();

if let Some(val) = endpoint.http2_keep_alive_timeout {
settings.http2_keep_alive_timeout(val);
#[cfg(target_arch = "wasm32")]
{
settings.executor(wasm::Executor);
}

if let Some(val) = endpoint.http2_keep_alive_while_idle {
settings.http2_keep_alive_while_idle(val);
}
// if let Some(val) = endpoint.http2_keep_alive_timeout {
// settings.http2_keep_alive_timeout(val);
// }

// if let Some(val) = endpoint.http2_keep_alive_while_idle {
// settings.http2_keep_alive_while_idle(val);
// }

let settings = settings.clone();

Expand Down
1 change: 1 addition & 0 deletions tonic/src/transport/service/discover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ impl<K: Hash + Eq + Clone> DynamicServiceStream<K> {
}
}

#[cfg(feature = "transport")]
impl<K: Hash + Eq + Clone> Discover for DynamicServiceStream<K> {
type Key = K;
type Service = Connection;
Expand Down
2 changes: 1 addition & 1 deletion tonic/src/transport/service/io.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::transport::{server::Connected, Certificate};
use crate::transport::{Certificate, Connected};
use hyper::client::connect::{Connected as HyperConnected, Connection};
use std::io;
use std::net::SocketAddr;
Expand Down

0 comments on commit b06a97d

Please sign in to comment.