diff options
author | Florian Klink <flokli@flokli.de> | 2023-11-13T12·32+0200 |
---|---|---|
committer | flokli <flokli@flokli.de> | 2023-11-15T06·43+0000 |
commit | 30e0c320666f8ecaf37f6d966e45c40f988cce78 (patch) | |
tree | 808bdb2c8832e2083bc17493dc8982b755486824 /tvix/castore/src/channel.rs | |
parent | c83841d3a13a5d5b3fdaa7f9beecd743f1283691 (diff) |
refactor(tvix/castore/tonic): make async, support wait-connect=? r/7022
This moves the sync `channel::from_url` to a async `tonic::channel_from_url`. It now allows connecting non-lazily if `wait- connect=1` is set in the URL params. Also, make the pingpong tests for blobsvc and directorysvc use the wait- connect=1 codepath. Change-Id: Ibeea33117c8121814627e7f6aba0e943ae2e92ca Reviewed-on: https://cl.tvl.fyi/c/depot/+/10030 Tested-by: BuildkiteCI Reviewed-by: Connor Brewster <cbrewster@hey.com>
Diffstat (limited to 'tvix/castore/src/channel.rs')
-rw-r--r-- | tvix/castore/src/channel.rs | 128 |
1 files changed, 0 insertions, 128 deletions
diff --git a/tvix/castore/src/channel.rs b/tvix/castore/src/channel.rs deleted file mode 100644 index 2fe97247679a..000000000000 --- a/tvix/castore/src/channel.rs +++ /dev/null @@ -1,128 +0,0 @@ -use tokio::net::UnixStream; -use tonic::transport::Channel; - -/// Turn a [url::Url] to a [Channel] if it can be parsed successfully. -/// It supports `grpc+unix:/path/to/socket`, -/// as well as the regular schemes supported by tonic, prefixed with grpc+, -/// for example `grpc+http://[::1]:8000`. -pub fn from_url(url: &url::Url) -> Result<Channel, self::Error> { - // Start checking for the scheme to start with grpc+. - // If it doesn't start with that, bail out. - match url.scheme().strip_prefix("grpc+") { - None => Err(Error::MissingGRPCPrefix()), - Some(rest) => { - if rest == "unix" { - if url.host_str().is_some() { - return Err(Error::HostSetForUnixSocket()); - } - - let url = url.clone(); - Ok( - tonic::transport::Endpoint::from_static("http://[::]:50051") // doesn't matter - .connect_with_connector_lazy(tower::service_fn( - move |_: tonic::transport::Uri| { - UnixStream::connect(url.path().to_string().clone()) - }, - )), - ) - } else { - // ensure path is empty, not supported with gRPC. - if !url.path().is_empty() { - return Err(Error::PathMayNotBeSet()); - } - - // Stringify the URL and remove the grpc+ prefix. - // We can't use `url.set_scheme(rest)`, as it disallows - // setting something http(s) that previously wasn't. - let url = url.to_string().strip_prefix("grpc+").unwrap().to_owned(); - - // Use the regular tonic transport::Endpoint logic to - Ok(tonic::transport::Endpoint::try_from(url) - .unwrap() - .connect_lazy()) - } - } - } -} - -/// Errors occuring when trying to connect to a backend -#[derive(Debug, thiserror::Error)] -pub enum Error { - #[error("grpc+ prefix is missing from Url")] - MissingGRPCPrefix(), - - #[error("host may not be set for unix domain sockets")] - HostSetForUnixSocket(), - - #[error("path may not be set")] - PathMayNotBeSet(), - - #[error("transport error: {0}")] - TransportError(tonic::transport::Error), -} - -impl From<tonic::transport::Error> for Error { - fn from(value: tonic::transport::Error) -> Self { - Self::TransportError(value) - } -} - -#[cfg(test)] -mod tests { - use super::from_url; - - /// This uses the correct scheme for a unix socket. - /// The fact that /path/to/somewhere doesn't exist yet is no problem, because we connect lazily. - #[tokio::test] - async fn test_valid_unix_path() { - let url = url::Url::parse("grpc+unix:///path/to/somewhere").expect("must parse"); - - assert!(from_url(&url).is_ok()) - } - - /// This uses the correct scheme for a unix socket, - /// but sets a host, which is unsupported. - #[tokio::test] - async fn test_invalid_unix_path_with_domain() { - let url = - url::Url::parse("grpc+unix://host.example/path/to/somewhere").expect("must parse"); - - assert!(from_url(&url).is_err()) - } - - /// This uses the wrong scheme - #[test] - fn test_invalid_scheme() { - let url = url::Url::parse("http://foo.example/test").expect("must parse"); - - assert!(from_url(&url).is_err()); - } - - /// This uses the correct scheme for a HTTP server. - /// The fact that nothing is listening there is no problem, because we connect lazily. - #[tokio::test] - async fn test_valid_http() { - let url = url::Url::parse("grpc+http://localhost").expect("must parse"); - - assert!(from_url(&url).is_ok()); - } - - /// This uses the correct scheme for a HTTPS server. - /// The fact that nothing is listening there is no problem, because we connect lazily. - #[tokio::test] - async fn test_valid_https() { - let url = url::Url::parse("grpc+https://localhost").expect("must parse"); - - assert!(from_url(&url).is_ok()); - } - - /// This uses the correct scheme, but also specifies - /// an additional path, which is not supported for gRPC. - /// The fact that nothing is listening there is no problem, because we connect lazily. - #[tokio::test] - async fn test_invalid_http_with_path() { - let url = url::Url::parse("grpc+https://localhost/some-path").expect("must parse"); - - assert!(from_url(&url).is_err()); - } -} |