Skip to content

Expose simultaneous access to Span and Inner on Instrumented so that implementation of foreign traits are possible #2804

Open
@Andrepuel

Description

@Andrepuel

Feature Request

Motivation

In my own crate I have a trait that represents some asynchronous work (similar to Stream trait). I wanted to support instrumenting on it. I.e. on my crate, I would provide impl<T: MyTrait> MyTrait for Instrumented<T> {.

On the poll() method of my trait I would enter the span, invoke the original T::poll and then exit the span. However, in order to do that I need simultaneous access to &Span and to Pin<&mut T>.

Proposal

In order to implement Future for Instrumented<T>, the tracing crate uses a private function called span_and_inner_pin_mut. A public version of this function could be exposed.

impl<T: MyTrait> MyTrait for Instrumented<T> {
    fn my_poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<()> {
        let (span, this) = self.span_and_inner_pin_mut();
        let _enter = span.enter();
        this.my_poll(cx)
    }
}

Alternatives

At the moment, it is possible to achieve the same goal by cloning the span from the reference that Instrumented provides, thus not borrowing the Instrumented. Since Instrumented is not borrowed, the public method inner_pin_mut may be used:

impl<T: MyTrait> MyTrait for Instrunmented<T> {
    fn my_poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<()> {
        let _enter = self.span().clone().entered();
        self.inner_pin_mut().poll(cx)
    }
 }

Metadata

Metadata

Assignees

No one assigned

    Labels

    crate/tracingRelated to the `tracing` cratekind/featureNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions