Skip to content

Commit f25a09c

Browse files
committed
Always create subspans on spawn
To ensure we do not have races on span enter and exit. Also fix the problem with subspan dying before blocking computation finishes. Caused by the use of `let _ = ...` instead of `let _p = ...`.
1 parent 52b22fe commit f25a09c

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

rust/datafusion/src/cube_ext/spawn.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,14 @@ where
2727
T: Future + Send + 'static,
2828
T::Output: Send + 'static,
2929
{
30-
tokio::spawn(task.in_current_span())
30+
if let Some(s) = new_subtask_span() {
31+
tokio::spawn(async move {
32+
let _p = s.parent; // ensure parent stays alive.
33+
task.instrument(s.child).await
34+
})
35+
} else {
36+
tokio::spawn(task)
37+
}
3138
}
3239

3340
/// Propagates current span to blocking operation. See [spawn] for details.
@@ -36,13 +43,27 @@ where
3643
F: FnOnce() -> R + Send + 'static,
3744
R: Send + 'static,
3845
{
39-
let span = tracing::Span::current();
40-
if span.is_disabled() {
41-
tokio::task::spawn_blocking(f)
42-
} else {
46+
if let Some(s) = new_subtask_span() {
4347
tokio::task::spawn_blocking(move || {
44-
let _ = tracing::info_span!(parent: &span, "blocking task").enter();
45-
f()
48+
let _p = s.parent; // ensure parent stays alive.
49+
s.child.in_scope(f)
4650
})
51+
} else {
52+
tokio::task::spawn_blocking(f)
53+
}
54+
}
55+
56+
struct SpawnSpans {
57+
parent: tracing::Span,
58+
child: tracing::Span,
59+
}
60+
61+
fn new_subtask_span() -> Option<SpawnSpans> {
62+
let parent = tracing::Span::current();
63+
if parent.is_disabled() {
64+
return None;
4765
}
66+
// TODO: ensure this is always enabled.
67+
let child = tracing::info_span!(parent: &parent, "subtask");
68+
Some(SpawnSpans { parent, child })
4869
}

0 commit comments

Comments
 (0)