diff --git a/vortex-io/src/runtime/handle.rs b/vortex-io/src/runtime/handle.rs index 3fc3203fae1..8675f051f19 100644 --- a/vortex-io/src/runtime/handle.rs +++ b/vortex-io/src/runtime/handle.rs @@ -68,7 +68,13 @@ impl Handle { R: Send + 'static, { let (send, recv) = oneshot::channel(); - let span = tracing::Span::current(); + // Instrument with a dedicated, named span on its own target rather than + // re-entering `Span::current()`. `Instrumented::poll` enters and exits the + // span on every poll, so re-entering the caller's span makes its cost scale + // with poll count. A distinct target lets subscribers opt these spans in or + // out via filtering; when filtered out the span is disabled and enter/exit + // are no-ops, which keeps frequently-polled spawned futures cheap. + let span = tracing::trace_span!(target: "vortex_io::spawn", "spawn"); let abort_handle = self.runtime().spawn( async move { // Task::detach allows the receiver to be dropped, so we ignore send errors. @@ -104,7 +110,11 @@ impl Handle { R: Send + 'static, { let (send, recv) = oneshot::channel(); - let span = tracing::Span::current(); + // See `spawn` above: a dedicated target rather than `Span::current()` so + // subscribers can filter these spans in or out. I/O futures are polled + // frequently, so disabling the span (the default for an unconfigured + // target) avoids per-poll enter/exit cost. + let span = tracing::trace_span!(target: "vortex_io::spawn_io", "spawn_io"); let abort_handle = self.runtime().spawn_io( async move { // Task::detach allows the receiver to be dropped, so we ignore send errors.