Audit drain, analysis, and settings regressions

This commit is contained in:
2026-03-29 20:24:08 -04:00
parent 3f28728b3e
commit 57e4a22be2
5 changed files with 32 additions and 13 deletions

View File

@@ -469,12 +469,15 @@ async fn run() -> Result<()> {
// Initialize File Watcher
let file_watcher = Arc::new(alchemist::system::watcher::FileWatcher::new(db.clone()));
// Initialize Library Scanner (shared between boot task and server)
let library_scanner = Arc::new(alchemist::system::scanner::LibraryScanner::new(
db.clone(),
config.clone(),
));
if !setup_mode {
let scan_agent = agent.clone();
let startup_scanner = Arc::new(alchemist::system::scanner::LibraryScanner::new(
db.clone(),
config.clone(),
));
let startup_scanner = library_scanner.clone();
tokio::spawn(async move {
// Small delay to let the server fully initialize
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
@@ -645,6 +648,7 @@ async fn run() -> Result<()> {
hardware_probe_log,
notification_manager: notification_manager.clone(),
file_watcher,
library_scanner,
})
.await?;
} else {

View File

@@ -734,7 +734,9 @@ impl Pipeline {
let analysis = match analyzer.analyze(&file_path).await {
Ok(m) => m,
Err(e) => {
tracing::error!("Job {}: Probing failed: {}", job.id, e);
let msg = format!("Probing failed: {e}");
tracing::error!("Job {}: {}", job.id, msg);
let _ = self.db.add_log("error", Some(job.id), &msg).await;
let _ = self
.update_job_state(job.id, crate::db::JobState::Failed)
.await;
@@ -773,7 +775,9 @@ impl Pipeline {
let profile = match self.db.get_profile_for_path(&job.input_path).await {
Ok(profile) => profile,
Err(err) => {
tracing::error!("Job {}: Failed to resolve library profile: {}", job.id, err);
let msg = format!("Failed to resolve library profile: {err}");
tracing::error!("Job {}: {}", job.id, msg);
let _ = self.db.add_log("error", Some(job.id), &msg).await;
let _ = self
.update_job_state(job.id, crate::db::JobState::Failed)
.await;
@@ -786,7 +790,9 @@ impl Pipeline {
{
Ok(plan) => plan,
Err(e) => {
tracing::error!("Job {}: Planner failed: {}", job.id, e);
let msg = format!("Planner failed: {e}");
tracing::error!("Job {}: {}", job.id, msg);
let _ = self.db.add_log("error", Some(job.id), &msg).await;
let _ = self
.update_job_state(job.id, crate::db::JobState::Failed)
.await;

View File

@@ -307,6 +307,10 @@ impl Agent {
);
self.stop_drain();
self.pause();
let _ = self
.event_channels
.system
.send(crate::db::SystemEvent::EngineStatusChanged);
}
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
continue;

View File

@@ -363,11 +363,13 @@ pub(crate) async fn get_job_detail_handler(
// Engine control handlers
pub(crate) async fn pause_engine_handler(State(state): State<Arc<AppState>>) -> impl IntoResponse {
state.agent.stop_drain();
state.agent.pause();
axum::Json(serde_json::json!({ "status": "paused" }))
}
pub(crate) async fn resume_engine_handler(State(state): State<Arc<AppState>>) -> impl IntoResponse {
state.agent.stop_drain();
state.agent.resume();
axum::Json(serde_json::json!({ "status": "running" }))
}

View File

@@ -101,6 +101,7 @@ pub struct RunServerArgs {
pub hardware_probe_log: Arc<tokio::sync::RwLock<HardwareProbeLog>>,
pub notification_manager: Arc<crate::notifications::NotificationManager>,
pub file_watcher: Arc<crate::system::watcher::FileWatcher>,
pub library_scanner: Arc<crate::system::scanner::LibraryScanner>,
}
pub async fn run_server(args: RunServerArgs) -> Result<()> {
@@ -119,6 +120,7 @@ pub async fn run_server(args: RunServerArgs) -> Result<()> {
hardware_probe_log,
notification_manager,
file_watcher,
library_scanner,
} = args;
#[cfg(not(feature = "embed-web"))]
{
@@ -140,11 +142,6 @@ pub async fn run_server(args: RunServerArgs) -> Result<()> {
sys.refresh_cpu_usage();
sys.refresh_memory();
let library_scanner = Arc::new(crate::system::scanner::LibraryScanner::new(
db.clone(),
config.clone(),
));
let state = Arc::new(AppState {
db,
config,
@@ -207,7 +204,12 @@ pub async fn run_server(args: RunServerArgs) -> Result<()> {
"Port {try_port} is already in use. Set ALCHEMIST_SERVER_PORT to a different port."
)));
}
tracing::warn!("Port {try_port} is in use, trying {}", try_port.saturating_add(1));
let next = try_port.saturating_add(1);
if attempt + 1 < max_attempts {
tracing::warn!("Port {try_port} is in use, trying {next}");
} else {
tracing::warn!("Port {try_port} is in use, no more ports to try");
}
}
Err(e) => return Err(AlchemistError::Io(e)),
}
@@ -225,6 +227,7 @@ pub async fn run_server(args: RunServerArgs) -> Result<()> {
"Port {} was in use — Alchemist is listening on http://0.0.0.0:{bound_port} instead",
port
);
info!("listening on http://0.0.0.0:{bound_port}");
} else {
info!("listening on http://0.0.0.0:{bound_port}");
}