Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions src/io_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use std::{
thread::Builder as ThreadBuilder,
time::Duration,
};
use tracing::{error, trace};
use tracing::{error, trace, Level};

const FRAMES_STORAGE: usize = 32;

Expand Down Expand Up @@ -159,12 +159,13 @@ impl IoLoop {
pub fn start(mut self) -> Result<()> {
let waker = self.socket_state.handle();
let handle = self.connection_io_loop_handle.clone();
let current_span = tracing::Span::current();
let connect_span = tracing::Span::current();
handle.register(
ThreadBuilder::new()
.name("lapin-io-loop".to_owned())
.spawn(move || {
let _enter = current_span.enter();
let loop_span = io_loop_span(connect_span);
let _enter = loop_span.enter();
let readable_waker = self.readable_waker();
let mut readable_context = Context::from_waker(&readable_waker);
let writable_waker = self.writable_waker();
Expand Down Expand Up @@ -457,3 +458,26 @@ impl IoLoop {
}
}
}

/// Create a new span for the io_loop thread that follows from the connect span, and has the same level.
///
/// Importantly, we drop the `connect_span` so it closes properly.
fn io_loop_span(connect_span: tracing::Span) -> tracing::Span {
let span_level = connect_span.metadata().unwrap().level();
let span = if *span_level == Level::ERROR {
tracing::span!(Level::ERROR, "io_loop")
} else if *span_level == Level::WARN {
tracing::span!(Level::WARN, "io_loop")
} else if *span_level == Level::INFO {
tracing::span!(Level::INFO, "io_loop")
} else if *span_level == Level::DEBUG {
tracing::span!(Level::DEBUG, "io_loop")
} else {
tracing::span!(Level::TRACE, "io_loop")
};

// This span doesn't contribute to the duration of the connect span, but it is caused by the
// connect operation, so we set it as a follows_from relationship.
span.follows_from(&connect_span);
span
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe all of this could be replaced with something like

let span_level = connect_span.metadata().map_or(Level::TRACE, |metadata| metadata.level());
tracing::span!(parent: connect_span, span_level, "io_loop")

Also, if you target the lapin-2.x branch instead, I'll cut a release for it, then merge in newer branch and cut 3.x and 4.x releases

Copy link
Contributor Author

@ThomWright ThomWright Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things:

  1. Span level – This can't be dynamic, otherwise yeah that approach would be better! You get this error:

    attempt to use a non-constant value in a constant non-constant value

    Which has serious "how much wood would a woodchuck chuck..." vibes.

    Yeah, this is a kind of annoying limitation of tracing.

  2. Relationship with connect span – I decided not to set the connect span as the parent. See the docs from tracing:

    In addition to having zero or one parent, a span may also follow from any number of other spans. This indicates a causal relationship between the span and the spans that it follows from, but a follower is not typically considered part of the duration of the span it follows.

    Which seems to match what we're trying to represent here.

  3. Branch target – Grand, I can change that 👍

}
Loading