Tracing: DAO layer + handler spans on tracing, drop all Context params (#141)
trace_db_call no longer takes an OpenTelemetry Context: it opens a db.<query_type>.<operation> span (same name via otel.name, same db.query_type / db.operation attrs) on the caller's ambient tracing span and runs the DAO body inside it. The cx / ctx / context parameter is gone from every DAO trait method, impl and call site, and from the helpers and background drains that only threaded it. The remaining request-handler spans (files, tags, faces, image, video, favorites, duplicates, memories) move to #[instrument]; the Context::current_with_span / with_remote_span_context plumbing is gone, as is extract_context_from_request (the tracing-actix-web root span covers it). otel::set_span_attributes replaces BoxedSpan::set_attributes. Background-job raw spans (thumbnails, video actors) are left for #142. tests/otel_db_spans.rs pins name, attributes, status and nesting (across an instrumented spawn); otel_traceparent now uses an #[instrument] handler. CLAUDE.md documents the tracing conventions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1c508cdabd
commit
b6deca2a52
55 files changed
+1942
-3852
No files matched your search
+14
-47
@@ -269,7 +269,7 @@ pub async fn get_prefs(_claims: Claims, app_state: web::Data<AppState>) -> HttpR
|
||||
}));
|
||||
}
|
||||
};
|
||||
match dao.get_prefs(&opentelemetry::Context::new()) {
|
||||
match dao.get_prefs() {
|
||||
Ok(row) => HttpResponse::Ok().json(row_to_response(row.as_ref())),
|
||||
Err(e) => HttpResponse::InternalServerError().json(json!({
|
||||
"error": format!("failed to read prefs: {e}")
|
||||
@@ -316,8 +316,7 @@ pub async fn put_prefs(
|
||||
}));
|
||||
}
|
||||
};
|
||||
let ctx = opentelemetry::Context::new();
|
||||
let existing = match dao.get_prefs(&ctx) {
|
||||
let existing = match dao.get_prefs() {
|
||||
Ok(row) => row,
|
||||
Err(e) => {
|
||||
return HttpResponse::InternalServerError().json(json!({
|
||||
@@ -362,7 +361,7 @@ pub async fn put_prefs(
|
||||
reel_max_segments: merged.reel_max_segments,
|
||||
updated_at: now,
|
||||
};
|
||||
match dao.upsert_prefs(&ctx, &upsert) {
|
||||
match dao.upsert_prefs(&upsert) {
|
||||
Ok(()) => HttpResponse::Ok().json(resp),
|
||||
Err(e) => HttpResponse::InternalServerError().json(json!({
|
||||
"error": format!("failed to write prefs: {e}")
|
||||
@@ -413,8 +412,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn seed(dao: &mut SqliteUserAiPrefsDao, row: UpsertUserAiPrefs) {
|
||||
dao.upsert_prefs(&opentelemetry::Context::new(), &row)
|
||||
.expect("seed prefs");
|
||||
dao.upsert_prefs(&row).expect("seed prefs");
|
||||
}
|
||||
|
||||
fn seeded_row(
|
||||
@@ -594,10 +592,7 @@ mod tests {
|
||||
assert_eq!(resp.status(), 200);
|
||||
|
||||
let mut dao = state.user_ai_prefs_dao.lock().unwrap();
|
||||
let row = dao
|
||||
.get_prefs(&opentelemetry::Context::new())
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let row = dao.get_prefs().unwrap().unwrap();
|
||||
assert_eq!(row.voice.as_deref(), Some("dad"));
|
||||
assert_eq!(row.library.as_deref(), Some("1"));
|
||||
assert_eq!(row.display_tz.as_deref(), Some("America/New_York"));
|
||||
@@ -634,10 +629,7 @@ mod tests {
|
||||
assert_eq!(resp.status(), 200);
|
||||
|
||||
let mut dao = state.user_ai_prefs_dao.lock().unwrap();
|
||||
let row = dao
|
||||
.get_prefs(&opentelemetry::Context::new())
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let row = dao.get_prefs().unwrap().unwrap();
|
||||
assert!(row.voice.is_none());
|
||||
assert_eq!(row.library.as_deref(), Some("1"));
|
||||
assert_eq!(row.display_tz.as_deref(), Some("America/New_York"));
|
||||
@@ -667,10 +659,7 @@ mod tests {
|
||||
assert_eq!(resp.status(), 200);
|
||||
|
||||
let mut dao = state.user_ai_prefs_dao.lock().unwrap();
|
||||
let row = dao
|
||||
.get_prefs(&opentelemetry::Context::new())
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let row = dao.get_prefs().unwrap().unwrap();
|
||||
assert_eq!(row.library.as_deref(), Some("1"));
|
||||
assert!(row.voice.is_none());
|
||||
assert!(row.display_tz.is_none());
|
||||
@@ -705,10 +694,7 @@ mod tests {
|
||||
|
||||
// Nothing written — not even the valid field in the same body.
|
||||
let mut dao = state.user_ai_prefs_dao.lock().unwrap();
|
||||
let row = dao
|
||||
.get_prefs(&opentelemetry::Context::new())
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let row = dao.get_prefs().unwrap().unwrap();
|
||||
assert_eq!(row.voice.as_deref(), Some("grandma"));
|
||||
assert_eq!(row.display_tz.as_deref(), Some("America/New_York"));
|
||||
assert_eq!(row.updated_at, 1_700_000_000);
|
||||
@@ -738,10 +724,7 @@ mod tests {
|
||||
assert_eq!(resp.status(), 200);
|
||||
|
||||
let mut dao = state.user_ai_prefs_dao.lock().unwrap();
|
||||
let row = dao
|
||||
.get_prefs(&opentelemetry::Context::new())
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let row = dao.get_prefs().unwrap().unwrap();
|
||||
assert_eq!(row.display_tz.as_deref(), Some("Europe/Berlin"));
|
||||
}
|
||||
|
||||
@@ -771,11 +754,7 @@ mod tests {
|
||||
assert_eq!(body["updated_at"], serde_json::Value::Null);
|
||||
|
||||
let mut dao = state.user_ai_prefs_dao.lock().unwrap();
|
||||
assert!(
|
||||
dao.get_prefs(&opentelemetry::Context::new())
|
||||
.unwrap()
|
||||
.is_none()
|
||||
);
|
||||
assert!(dao.get_prefs().unwrap().is_none());
|
||||
}
|
||||
|
||||
// --- GET /timezones -----------------------------------------------------
|
||||
@@ -918,10 +897,7 @@ mod tests {
|
||||
assert_eq!(resp.status(), 200);
|
||||
|
||||
let mut dao = state.user_ai_prefs_dao.lock().unwrap();
|
||||
let row = dao
|
||||
.get_prefs(&opentelemetry::Context::new())
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let row = dao.get_prefs().unwrap().unwrap();
|
||||
assert_eq!(row.default_model.as_deref(), Some("llama3.2:3b"));
|
||||
assert_eq!(row.default_backend.as_deref(), Some("hybrid"));
|
||||
assert_eq!(row.default_persona_id.as_deref(), Some("cabin"));
|
||||
@@ -963,10 +939,7 @@ mod tests {
|
||||
assert_eq!(resp.status(), 200);
|
||||
|
||||
let mut dao = state.user_ai_prefs_dao.lock().unwrap();
|
||||
let row = dao
|
||||
.get_prefs(&opentelemetry::Context::new())
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let row = dao.get_prefs().unwrap().unwrap();
|
||||
assert!(row.default_model.is_none());
|
||||
assert!(row.default_backend.is_none());
|
||||
assert!(row.default_persona_id.is_none());
|
||||
@@ -1004,10 +977,7 @@ mod tests {
|
||||
assert_eq!(resp.status(), 400);
|
||||
|
||||
let mut dao = state.user_ai_prefs_dao.lock().unwrap();
|
||||
let row = dao
|
||||
.get_prefs(&opentelemetry::Context::new())
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let row = dao.get_prefs().unwrap().unwrap();
|
||||
// Nothing written — not even the valid field in the same body.
|
||||
assert_eq!(row.voice.as_deref(), Some("grandma"));
|
||||
assert!(row.default_backend.is_none());
|
||||
@@ -1056,10 +1026,7 @@ mod tests {
|
||||
assert_eq!(resp.status(), 400);
|
||||
|
||||
let mut dao = state.user_ai_prefs_dao.lock().unwrap();
|
||||
let row = dao
|
||||
.get_prefs(&opentelemetry::Context::new())
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let row = dao.get_prefs().unwrap().unwrap();
|
||||
assert!(row.reel_span.is_none());
|
||||
assert_eq!(row.updated_at, 1_700_000_000);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user