diff --git a/Cargo.lock b/Cargo.lock index 167acf0e69..2cd7ba44d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2859,22 +2859,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.0.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.15", ] [[package]] @@ -4979,6 +4979,7 @@ dependencies = [ "metrics", "nix", "once_cell", + "pin-project", "pin-project-lite", "pq_proto", "rand", diff --git a/libs/utils/Cargo.toml b/libs/utils/Cargo.toml index 8239ffff57..634d251515 100644 --- a/libs/utils/Cargo.toml +++ b/libs/utils/Cargo.toml @@ -41,6 +41,9 @@ pq_proto.workspace = true metrics.workspace = true workspace_hack.workspace = true +# needed to have pin-projected with PinnedDrop +pin-project = "1.1" + [dev-dependencies] byteorder.workspace = true bytes.workspace = true diff --git a/libs/utils/src/lib.rs b/libs/utils/src/lib.rs index 4e4f79ab6b..1183bdd33c 100644 --- a/libs/utils/src/lib.rs +++ b/libs/utils/src/lib.rs @@ -147,3 +147,56 @@ macro_rules! const_assert { const _: () = assert!($($args)*); }; } + +pub mod cancel_log { + pub trait CancelationLoggingExt { + fn log_being_canceled(self, step: &'static str) -> LogCancelation + where + Self: Sized; + } + + impl CancelationLoggingExt for Fut { + fn log_being_canceled(self, step: &'static str) -> LogCancelation + where + Self: Sized, + { + LogCancelation { + inner: self, + name: Some(step), + span: tracing::Span::current(), + } + } + } + + #[pin_project::pin_project(PinnedDrop)] + pub struct LogCancelation { + #[pin] + inner: Fut, + name: Option<&'static str>, + span: tracing::Span, + } + + impl std::future::Future for LogCancelation { + type Output = Fut::Output; + + fn poll( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { + let this = self.project(); + let ready = std::task::ready!(this.inner.poll(cx)); + this.name.take(); + std::task::Poll::Ready(ready) + } + } + + #[pin_project::pinned_drop] + impl PinnedDrop for LogCancelation { + fn drop(self: std::pin::Pin<&mut Self>) { + if let Some(name) = self.name { + let _g = self.span.enter(); + tracing::info!("canceled while waiting for {name}"); + } + } + } +} diff --git a/pageserver/src/http/routes.rs b/pageserver/src/http/routes.rs index 91f4fda5eb..fe23187f4f 100644 --- a/pageserver/src/http/routes.rs +++ b/pageserver/src/http/routes.rs @@ -29,6 +29,7 @@ use crate::tenant::{LogicalSizeCalculationCause, PageReconstructError, Timeline} use crate::{config::PageServerConf, tenant::mgr}; use utils::{ auth::JwtAuth, + cancel_log::CancelationLoggingExt, http::{ endpoint::{self, attach_openapi_ui, auth_middleware, check_permission_with}, error::{ApiError, HttpErrorBody}, @@ -186,6 +187,7 @@ async fn build_timeline_info( CancellationToken::new(), ctx, ) + .log_being_canceled("get_current_logical_size_non_incremental") .await?, ); } @@ -338,7 +340,9 @@ async fn timeline_detail_handler(request: Request) -> Result) -> Result) -> Result(timeline_info) } .instrument(info_span!("timeline_detail", tenant = %tenant_id, timeline = %timeline_id)) + .log_being_canceled("whole response") .await?; json_response(StatusCode::OK, timeline_info)