diff --git a/CHANGELOG.md b/CHANGELOG.md index 50a0776..6987d87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.9.0](https://github.com/TrueLayer/ginepro/compare/ginepro-v0.8.2...ginepro-v0.8.1) - 2025-07-24 + +### Breaking changes +- Update to **tonic** 0.13 +- Update to **tower** 0.5 +- Update to **hickory-resolver** 0.25 +- Update to **thiserror** 2 + ## [0.8.2](https://github.com/TrueLayer/ginepro/compare/ginepro-v0.8.2...ginepro-v0.8.1) - 2024-12-09 ### Other diff --git a/ginepro/Cargo.toml b/ginepro/Cargo.toml index e7bf072..0e5dfd7 100644 --- a/ginepro/Cargo.toml +++ b/ginepro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ginepro" -version = "0.8.2" +version = "0.9.0" edition = "2021" description = "A client-side gRPC channel implementation for tonic" repository = "https://github.com/TrueLayer/ginepro" @@ -13,12 +13,12 @@ readme = "../README.md" anyhow = "1" async-trait = "0.1" http = "1" -thiserror = "1" +thiserror = "2" tokio = { version = "1", features = ["full"] } -tonic = { version = "0.12", features = ["tls"] } -tower = { version = "0.4", default-features = false, features = ["discover"] } +tonic = { version = "0.13", features = ["tls-ring"] } +tower = { version = "0.5", default-features = false, features = ["discover"] } tracing = "0.1" -hickory-resolver = { version = "0.24", features = ["tokio-runtime"] } +hickory-resolver = { version = "0.25", features = ["tokio"] } [dev-dependencies] proptest = "1" diff --git a/ginepro/examples/client.rs b/ginepro/examples/client.rs index 5442032..ff81e18 100644 --- a/ginepro/examples/client.rs +++ b/ginepro/examples/client.rs @@ -22,7 +22,7 @@ async fn main() -> Result<(), Box> { let response = client.unary_echo(request).await?; - println!("RESPONSE={:?}", response); + println!("RESPONSE={response:?}"); Ok(()) } diff --git a/ginepro/examples/client_tls.rs b/ginepro/examples/client_tls.rs index 7a0e3bc..e09a9ee 100644 --- a/ginepro/examples/client_tls.rs +++ b/ginepro/examples/client_tls.rs @@ -1,9 +1,7 @@ use ginepro::LoadBalancedChannel; -use tonic::transport::Certificate; -use tonic::transport::ClientTlsConfig; +use tonic::transport::{Certificate, ClientTlsConfig}; -use shared_proto::pb::echo_client::EchoClient; -use shared_proto::pb::EchoRequest; +use shared_proto::pb::{echo_client::EchoClient, EchoRequest}; use tests::tls::TestSslCertificate; #[tokio::main] @@ -30,7 +28,7 @@ async fn main() -> Result<(), Box> { let response = client.unary_echo(request).await?; - println!("RESPONSE={:?}", response); + println!("RESPONSE={response:?}"); Ok(()) } diff --git a/ginepro/examples/resolution_strategy.rs b/ginepro/examples/resolution_strategy.rs index 4af2800..11d6991 100644 --- a/ginepro/examples/resolution_strategy.rs +++ b/ginepro/examples/resolution_strategy.rs @@ -28,7 +28,7 @@ async fn main() -> Result<(), Box> { let response = client.unary_echo(request).await?; - println!("RESPONSE={:?}", response); + println!("RESPONSE={response:?}"); Ok(()) } diff --git a/ginepro/src/balanced_channel.rs b/ginepro/src/balanced_channel.rs index eea84c3..bf0f681 100644 --- a/ginepro/src/balanced_channel.rs +++ b/ginepro/src/balanced_channel.rs @@ -9,12 +9,13 @@ use anyhow::Context as _; use http::Request; use std::{ convert::TryInto, + net::SocketAddr, task::{Context, Poll}, }; use tokio::time::Duration; -use tonic::client::GrpcService; use tonic::transport::channel::Channel; -use tonic::{body::BoxBody, transport::ClientTlsConfig}; +use tonic::transport::ClientTlsConfig; +use tonic::{body::Body, client::GrpcService}; use tower::Service; // Determines the channel size of the channel we use @@ -69,16 +70,16 @@ impl LoadBalancedChannel { } } -impl Service> for LoadBalancedChannel { - type Response = http::Response<>::ResponseBody>; - type Error = >::Error; - type Future = >::Future; +impl Service> for LoadBalancedChannel { + type Response = http::Response<>::ResponseBody>; + type Error = >::Error; + type Future = >::Future; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { GrpcService::poll_ready(&mut self.0, cx) } - fn call(&mut self, request: Request) -> Self::Future { + fn call(&mut self, request: Request) -> Self::Future { GrpcService::call(&mut self.0, request) } } @@ -220,7 +221,8 @@ where where U: LookupService + Send + Sync + 'static + Sized, { - let (channel, sender) = Channel::balance_channel(GRPC_REPORT_ENDPOINTS_CHANNEL_SIZE); + let (channel, sender) = + Channel::balance_channel::(GRPC_REPORT_ENDPOINTS_CHANNEL_SIZE); let config = GrpcServiceProbeConfig { service_definition: self diff --git a/ginepro/src/dns_resolver.rs b/ginepro/src/dns_resolver.rs index 88f87c5..9d740af 100644 --- a/ginepro/src/dns_resolver.rs +++ b/ginepro/src/dns_resolver.rs @@ -1,30 +1,28 @@ //! Implements [`LookupService`] for dns. use crate::{LookupService, ServiceDefinition}; -use anyhow::Context; -use hickory_resolver::{system_conf, AsyncResolver, TokioAsyncResolver}; -use std::collections::HashSet; -use std::net::SocketAddr; +use hickory_resolver::TokioResolver; +use std::{collections::HashSet, net::SocketAddr}; /// Implements [`LookupService`] by using DNS queries to lookup [`ServiceDefinition::hostname`]. pub struct DnsResolver { /// The trust-dns resolver which contacts the dns service directly such /// that we bypass os-specific dns caching. - dns: TokioAsyncResolver, + dns: TokioResolver, } impl DnsResolver { /// Construct a new [`DnsResolver`] from env and system configuration, e.g `resolv.conf`. pub async fn from_system_config() -> Result { - let (config, mut opts) = system_conf::read_system_conf() - .context("failed to read dns services from system configuration")?; + let mut builder = TokioResolver::builder_tokio()?; // We do not want any caching on our side. + let opts = builder.options_mut(); opts.cache_size = 0; - let dns = AsyncResolver::tokio(config, opts); - - Ok(Self { dns }) + Ok(Self { + dns: builder.build(), + }) } } diff --git a/ginepro/src/service_probe.rs b/ginepro/src/service_probe.rs index 535d2fa..0e65708 100644 --- a/ginepro/src/service_probe.rs +++ b/ginepro/src/service_probe.rs @@ -2,8 +2,10 @@ use crate::{LookupService, ServiceDefinition}; use std::collections::HashSet; use std::net::SocketAddr; use tokio::sync::mpsc::Sender; -use tonic::transport::{channel::Endpoint, ClientTlsConfig}; -use tower::discover::Change; +use tonic::transport::{ + channel::{Change, Endpoint}, + ClientTlsConfig, +}; #[derive(thiserror::Error, Debug)] pub enum ProbeError { diff --git a/shared_proto/Cargo.toml b/shared_proto/Cargo.toml index ee1e75f..3f3dde8 100644 --- a/shared_proto/Cargo.toml +++ b/shared_proto/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] prost = "0.13" -tonic = "0.12" +tonic = "0.13" [build-dependencies] -tonic-build = "0.12" +tonic-build = "0.13" diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 53a2900..1391a8e 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -13,7 +13,7 @@ hyper = "1" openssl = "0.10" tokio = { version = "1", features = ["full"] } tokio-stream = { version = "0.1", features = ["net"] } -tonic = { version = "0.12", features = ["tls"] } +tonic = { version = "0.13", features = ["tls-ring"] } tower-layer = "0.3" tower-service = "0.3" tracing = { version = "0.1", features = ["attributes", "log"] } @@ -22,4 +22,4 @@ tracing = { version = "0.1", features = ["attributes", "log"] } anyhow = "1" async-trait = "0.1" shared-proto = { path = "../shared_proto" } -tonic-health = "0.12" +tonic-health = "0.13" diff --git a/tests/src/test_server.rs b/tests/src/test_server.rs index e0fd478..5736770 100644 --- a/tests/src/test_server.rs +++ b/tests/src/test_server.rs @@ -7,13 +7,14 @@ use std::{ use tokio::net::{TcpListener, TcpStream}; use tokio_stream::wrappers::TcpListenerStream; use tonic::{ - body::BoxBody, + body::Body, + server::NamedService, + service::Routes, transport::{ server::{Router, Server}, ServerTlsConfig, }, }; -use tonic::{server::NamedService, service::Routes}; use tower_layer::Layer; use tower_service::Service; @@ -45,10 +46,11 @@ impl TestServer { tls: Option, ) -> Self where - S: Service, Response = Response, Error = Infallible> + S: Service, Response = Response, Error = Infallible> + NamedService + Clone + Send + + Sync + 'static, S::Future: Send + 'static, S::Error: Into> + Send, @@ -86,10 +88,9 @@ impl TestServer { pub async fn start_with_router(router: Router, address: T) -> TestServer where L: Layer + Send + 'static, - L::Service: - Service, Response = Response> + Clone + Send + 'static, - <>::Service as Service>>::Future: Send + 'static, - <>::Service as Service>>::Error: + L::Service: Service, Response = Response> + Clone + Send + 'static, + <>::Service as Service>>::Future: Send + 'static, + <>::Service as Service>>::Error: Into> + Send, T: Into>, { @@ -116,7 +117,7 @@ impl TestServer { let wait_start = Instant::now(); while let Err(e) = TcpStream::connect(listener_addr).await { if wait_start.elapsed() > Duration::from_secs(10) { - panic!("Cannot connect to {}: {}", listener_addr, e); + panic!("Cannot connect to {listener_addr}: {e}"); } tokio::task::yield_now().await; }