diff --git a/ginepro/Cargo.toml b/ginepro/Cargo.toml index 0e5dfd7..f8aea41 100644 --- a/ginepro/Cargo.toml +++ b/ginepro/Cargo.toml @@ -15,7 +15,7 @@ async-trait = "0.1" http = "1" thiserror = "2" tokio = { version = "1", features = ["full"] } -tonic = { version = "0.13", features = ["tls-ring"] } +tonic = { version = "0.14", features = ["tls-ring"] } tower = { version = "0.5", default-features = false, features = ["discover"] } tracing = "0.1" hickory-resolver = { version = "0.25", features = ["tokio"] } diff --git a/ginepro/src/service_probe.rs b/ginepro/src/service_probe.rs index 0e65708..5f7c4de 100644 --- a/ginepro/src/service_probe.rs +++ b/ginepro/src/service_probe.rs @@ -93,11 +93,22 @@ impl GrpcServiceProbe { } /// Start probing the provided `hostname` for IP address changes. - /// The function will error if the receiving end of the tonic balance channel - /// is closed, e.g, the client has been deconstructed. + /// The probe loop exits once the receiving end of the tonic balance channel is closed, + /// e.g. when the client has been dropped. /// Any other errors are seen as transient, and therefore retried after `self.probe_interval`. pub async fn probe(mut self) -> Result<(), anyhow::Error> { + let client_closed_err = || { + anyhow::anyhow!( + "The gRPC client has closed the channel therefore the DNS probe loop will exit." + ) + }; + loop { + // If the receiver is already gone (e.g. client dropped), exit promptly. + if self.endpoint_reporter.is_closed() { + return Err(client_closed_err()); + } + self.probe_once().await.or_else(|err| { // Only terminate if the changeset channel has been closed. if let ProbeError::ChangesetSenderClosed(_) = err { @@ -107,7 +118,10 @@ impl GrpcServiceProbe { } })?; - tokio::time::sleep(self.probe_interval).await; + tokio::select! { + _ = self.endpoint_reporter.closed() => return Err(client_closed_err()), + _ = tokio::time::sleep(self.probe_interval) => {}, + } } } diff --git a/shared_proto/Cargo.toml b/shared_proto/Cargo.toml index 3f3dde8..43cb180 100644 --- a/shared_proto/Cargo.toml +++ b/shared_proto/Cargo.toml @@ -6,8 +6,9 @@ edition = "2021" publish = false [dependencies] -prost = "0.13" -tonic = "0.13" +prost = "0.14" +tonic = "0.14" +tonic-prost = "0.14" [build-dependencies] -tonic-build = "0.13" +tonic-prost-build = "0.14" diff --git a/shared_proto/build.rs b/shared_proto/build.rs index 59fdd38..f8b5d70 100644 --- a/shared_proto/build.rs +++ b/shared_proto/build.rs @@ -3,7 +3,7 @@ //! tonic functionality. fn main() -> Result<(), Box> { - tonic_build::configure() + tonic_prost_build::configure() .build_server(true) .build_client(true) .compile_protos(&["proto/test.proto", "proto/echo.proto"], &["proto/"])?; diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 1391a8e..6342ca4 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.13", features = ["tls-ring"] } +tonic = { version = "0.14", 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.13" +tonic-health = "0.14"