agent: code-atomiser-fix — test_llm_model respects caller GPU preference (Race-8)
Add an Option<bool> use_gpu parameter to test_llm_model with the same default-true semantics as load_llm_model. Hard-coding true triggered an engine tear-down/rebuild when a parallel load_llm_model(use_gpu=false) was in flight (LlmEngine::load_model triples on id+path+use_gpu) and silently flipped the user's GPU mode underneath the test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,13 +5,18 @@ mod tauri_app_data_migration;
|
||||
#[cfg(not(target_os = "android"))]
|
||||
mod tray;
|
||||
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Once;
|
||||
use std::sync::{Once, OnceLock};
|
||||
use std::time::Instant;
|
||||
|
||||
use sqlx::SqlitePool;
|
||||
use tauri::Manager;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
use tracing_appender::non_blocking::WorkerGuard;
|
||||
use tracing_appender::rolling::{RollingFileAppender, Rotation};
|
||||
use tracing_subscriber::layer::SubscriberExt;
|
||||
use tracing_subscriber::util::SubscriberInitExt;
|
||||
use tracing_subscriber::{EnvFilter, Layer};
|
||||
|
||||
use lumotia_core::paths::{
|
||||
check_target_ambiguity, migrate_legacy_data_dir, MigrationStatus,
|
||||
@@ -31,6 +36,13 @@ use lumotia_transcription::LocalEngine;
|
||||
|
||||
static TRACING_INIT: Once = Once::new();
|
||||
|
||||
/// Parks the non-blocking file-appender's `WorkerGuard` for the process
|
||||
/// lifetime. Dropping the guard halts the background log-writing thread
|
||||
/// and discards any pending log lines, so it must outlive every
|
||||
/// `tracing::*!` call. A `OnceLock` here gives us a free `'static`
|
||||
/// home and matches the `Once`-guarded init pattern above.
|
||||
static FILE_APPENDER_GUARD: OnceLock<WorkerGuard> = OnceLock::new();
|
||||
|
||||
/// Shared app state holding the transcription engines and database pool.
|
||||
pub struct AppState {
|
||||
pub whisper_engine: Arc<LocalEngine>,
|
||||
@@ -165,18 +177,112 @@ fn warn_if_x11_env_unset_on_wayland() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Default `EnvFilter` string for the stderr (developer-facing) layer.
|
||||
///
|
||||
/// `lumotia_lib::commands::live=info` is listed explicitly so that the
|
||||
/// operator's documented triage filter (per
|
||||
/// docs/superpowers/audits/2026-05-10-phase10a-dogfood-notes.md) works
|
||||
/// without a manual `RUST_LOG=` override on every dogfooding session.
|
||||
const DEFAULT_STDERR_FILTER: &str =
|
||||
"warn,lumotia=info,lumotia_lib=info,lumotia_lib::commands::live=info,lumotia_core=info,lumotia_audio=info,lumotia_hotkey=info,lumotia_ai_formatting=info,lumotia_llm=info,lumotia_storage=info,lumotia_transcription=info,lumotia_startup=info";
|
||||
|
||||
/// Default `EnvFilter` string for the rolling-file (forensic) layer.
|
||||
///
|
||||
/// More verbose than stderr by design: the file is what users attach to
|
||||
/// diagnostic reports, so DEBUG-level Lumotia internals are worth the
|
||||
/// disk cost. Third-party crates that spam at DEBUG (`sqlx`, `hyper`,
|
||||
/// `reqwest`, `h2`, `rustls`, `tokio_util`) are pinned at INFO so they
|
||||
/// don't drown out our own log lines.
|
||||
const DEFAULT_FILE_FILTER: &str =
|
||||
"info,lumotia=debug,lumotia_lib=debug,lumotia_lib::commands::live=debug,lumotia_core=debug,lumotia_audio=debug,lumotia_hotkey=debug,lumotia_ai_formatting=debug,lumotia_llm=debug,lumotia_storage=debug,lumotia_transcription=debug,lumotia_startup=debug,sqlx=info,hyper=info,reqwest=info,h2=info,rustls=info,tokio_util=info";
|
||||
|
||||
/// Build the stderr-side `EnvFilter`, honouring `RUST_LOG` if set.
|
||||
fn stderr_env_filter() -> EnvFilter {
|
||||
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(DEFAULT_STDERR_FILTER))
|
||||
}
|
||||
|
||||
/// Build the file-side `EnvFilter`, honouring `LUMOTIA_LOG_FILE` if set
|
||||
/// (falling back to `RUST_LOG`, then the verbose default).
|
||||
fn file_env_filter() -> EnvFilter {
|
||||
EnvFilter::try_from_env("LUMOTIA_LOG_FILE")
|
||||
.or_else(|_| EnvFilter::try_from_default_env())
|
||||
.unwrap_or_else(|_| EnvFilter::new(DEFAULT_FILE_FILTER))
|
||||
}
|
||||
|
||||
/// Build the rolling daily appender for `lumotia.log` inside `logs_dir`.
|
||||
///
|
||||
/// Rotation policy: one file per day, keep 7 most-recent days. Older
|
||||
/// files are pruned by `tracing-appender` itself. The base filename is
|
||||
/// `lumotia.log`; rotated files get a date suffix (e.g.
|
||||
/// `lumotia.log.2026-05-12`).
|
||||
fn build_rolling_appender(logs_dir: &Path) -> std::io::Result<RollingFileAppender> {
|
||||
std::fs::create_dir_all(logs_dir)?;
|
||||
RollingFileAppender::builder()
|
||||
.rotation(Rotation::DAILY)
|
||||
.filename_prefix("lumotia")
|
||||
.filename_suffix("log")
|
||||
.max_log_files(7)
|
||||
.build(logs_dir)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))
|
||||
}
|
||||
|
||||
/// Install a `tracing` subscriber that writes to stderr (developer
|
||||
/// stream, ANSI-coloured) AND to a rolling daily file at
|
||||
/// `logs_dir/lumotia.log` (forensic stream, plain text). The file
|
||||
/// stream is what diagnostic-report bundles attach.
|
||||
///
|
||||
/// Returns the `WorkerGuard` for the file appender so the caller can
|
||||
/// park it for the process lifetime; dropping it discards pending logs.
|
||||
/// Returns `None` if the file appender could not be built (e.g.
|
||||
/// permissions); in that case only the stderr layer is installed.
|
||||
///
|
||||
/// Exposed `pub` so the `tracing_appender_smoke` integration test can
|
||||
/// drive it against a tempdir; production code calls it via
|
||||
/// `init_tracing` against the platform-default `logs_dir()`.
|
||||
pub fn install_subscriber(logs_dir: &Path) -> Option<WorkerGuard> {
|
||||
let stderr_layer = tracing_subscriber::fmt::layer()
|
||||
.with_writer(std::io::stderr)
|
||||
.with_filter(stderr_env_filter());
|
||||
|
||||
match build_rolling_appender(logs_dir) {
|
||||
Ok(appender) => {
|
||||
let (non_blocking, guard) = tracing_appender::non_blocking(appender);
|
||||
let file_layer = tracing_subscriber::fmt::layer()
|
||||
.with_writer(non_blocking)
|
||||
.with_ansi(false)
|
||||
.with_filter(file_env_filter());
|
||||
|
||||
let _ = tracing_subscriber::registry()
|
||||
.with(stderr_layer)
|
||||
.with(file_layer)
|
||||
.try_init();
|
||||
Some(guard)
|
||||
}
|
||||
Err(e) => {
|
||||
// Best-effort: keep stderr logging even if the file path is
|
||||
// unwritable, and surface the failure to stderr so dogfooders
|
||||
// notice the missing forensic stream.
|
||||
let _ = tracing_subscriber::registry()
|
||||
.with(stderr_layer)
|
||||
.try_init();
|
||||
eprintln!(
|
||||
"lumotia: failed to install rolling file log appender at {}: {e}",
|
||||
logs_dir.display()
|
||||
);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn init_tracing() {
|
||||
TRACING_INIT.call_once(|| {
|
||||
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| {
|
||||
EnvFilter::new(
|
||||
"warn,lumotia=info,lumotia_lib=info,lumotia_core=info,lumotia_audio=info,lumotia_hotkey=info,lumotia_ai_formatting=info,lumotia_llm=info,lumotia_storage=info,lumotia_transcription=info,lumotia_startup=info",
|
||||
)
|
||||
});
|
||||
|
||||
let _ = tracing_subscriber::fmt()
|
||||
.with_env_filter(env_filter)
|
||||
.with_writer(std::io::stderr)
|
||||
.try_init();
|
||||
let logs_dir = lumotia_storage::file_storage::logs_dir();
|
||||
if let Some(guard) = install_subscriber(&logs_dir) {
|
||||
// Park the guard for the process lifetime. set() only fails
|
||||
// if already set (impossible inside Once::call_once), so we
|
||||
// ignore the result.
|
||||
let _ = FILE_APPENDER_GUARD.set(guard);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user