Tracing: root spans for background jobs, retire raw OTel spans (#142)
Background work has no request parent, so each job now opens a named tracing root and carries it into its fan-out: - watcher: `watcher.tick` (scan=quick|full) entered per tick on the watcher's std thread, `watcher.library` per library, and `watcher.playlist_cleanup` per orphaned-HLS pass. face_watch / clip_watch carry the ambient span into every per-candidate tokio::spawn and give each call its own `face_watch.detect` / `clip_watch.encode` span. - thumbnails: `creating thumbnails` via #[instrument]; per-video spans on rayon workers name their parent explicitly. - video actors: `playlistgenerator.generate_playlist` and `preview_clip.generate` are tracing roots that instrument their futures. - reels: `reel.job` (created before the spawn, so on-demand jobs stay in the request trace), `reel.pregen_batch`, `reel.cache_sweep`. - RefreshThumbnailsMessage and the dead-code GIF job move to tracing. No raw OpenTelemetry span creation is left outside otel.rs; `global_tracer` is removed. tests/otel_background.rs pins the std-thread tick -> block_on -> spawn shape and the rayon explicit-parent shape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b6deca2a52
commit
26115b3378
11 files changed
+330
-179
No files matched your search
+13
-4
@@ -29,6 +29,7 @@ use log::{debug, info, warn};
|
||||
use std::path::Path;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tokio::sync::Semaphore;
|
||||
use tracing::Instrument;
|
||||
|
||||
/// One file the watcher would like to CLIP-encode. Built from the DAO
|
||||
/// `list_clip_unencoded_candidates` result — needs the `content_hash`
|
||||
@@ -90,6 +91,9 @@ pub fn run_clip_encoding_pass(
|
||||
|
||||
let library_id = library.id;
|
||||
let library_root = library.root_path.clone();
|
||||
// The detect tasks run on this runtime's worker threads; carry the
|
||||
// watcher's span into each so their spans stay in the tick's trace.
|
||||
let parent = tracing::Span::current();
|
||||
rt.block_on(async move {
|
||||
let sem = Arc::new(Semaphore::new(concurrency));
|
||||
let mut handles = Vec::with_capacity(filtered.len());
|
||||
@@ -98,10 +102,14 @@ pub fn run_clip_encoding_pass(
|
||||
let clip_client = clip_client.clone();
|
||||
let exif_dao = exif_dao.clone();
|
||||
let library_root = library_root.clone();
|
||||
handles.push(tokio::spawn(async move {
|
||||
let _permit = permit_sem.acquire().await.expect("clip semaphore");
|
||||
process_one(library_id, &library_root, cand, &clip_client, exif_dao).await;
|
||||
}));
|
||||
let task_span = parent.clone();
|
||||
handles.push(tokio::spawn(
|
||||
async move {
|
||||
let _permit = permit_sem.acquire().await.expect("clip semaphore");
|
||||
process_one(library_id, &library_root, cand, &clip_client, exif_dao).await;
|
||||
}
|
||||
.instrument(task_span),
|
||||
));
|
||||
}
|
||||
for h in handles {
|
||||
let _ = h.await;
|
||||
@@ -109,6 +117,7 @@ pub fn run_clip_encoding_pass(
|
||||
});
|
||||
}
|
||||
|
||||
#[tracing::instrument(name = "clip_watch.encode", skip_all, fields(rel_path = %cand.rel_path))]
|
||||
async fn process_one(
|
||||
library_id: i32,
|
||||
library_root: &str,
|
||||
|
||||
Reference in new issue
Block a user