|
1 | | -use crate::jobs::{Job, JobProgress, JobQueue, JobStatus, Quadrant, VideoQuadrantSelection, WebDavConfig}; |
| 1 | +use crate::jobs::{Job, JobProgress, JobQueue, JobStatus, LogEntry, Quadrant, VideoQuadrantSelection, WebDavConfig}; |
2 | 2 | use crate::webdav::WebDavClient; |
3 | 3 | use anyhow::Result; |
4 | 4 | use axum::{ |
@@ -90,6 +90,7 @@ pub async fn run_server(port: u16, data_dir: &str) -> Result<()> { |
90 | 90 | .route("/api/jobs/pending", get(get_pending_job)) |
91 | 91 | .route("/api/jobs/claim", post(claim_job)) |
92 | 92 | .route("/api/jobs/{id}/progress", patch(update_job_progress)) |
| 93 | + .route("/api/jobs/{id}/logs", post(append_job_logs)) |
93 | 94 | .route("/health", get(health_check)) |
94 | 95 | // Static files for worker provisioning |
95 | 96 | .route("/assets/worker", get(serve_worker_binary)) |
@@ -456,6 +457,49 @@ async fn update_job_progress( |
456 | 457 | } |
457 | 458 | } |
458 | 459 |
|
| 460 | +#[derive(Debug, Deserialize)] |
| 461 | +struct AppendLogsRequest { |
| 462 | + logs: Vec<LogEntryRequest>, |
| 463 | +} |
| 464 | + |
| 465 | +#[derive(Debug, Deserialize)] |
| 466 | +struct LogEntryRequest { |
| 467 | + timestamp: String, |
| 468 | + level: String, |
| 469 | + message: String, |
| 470 | +} |
| 471 | + |
| 472 | +/// Append log entries to a job |
| 473 | +async fn append_job_logs( |
| 474 | + State(state): State<AppState>, |
| 475 | + Path(id): Path<String>, |
| 476 | + Json(req): Json<AppendLogsRequest>, |
| 477 | +) -> Response { |
| 478 | + let logs: Vec<LogEntry> = req.logs.into_iter().map(|l| { |
| 479 | + LogEntry { |
| 480 | + timestamp: chrono::DateTime::parse_from_rfc3339(&l.timestamp) |
| 481 | + .map(|dt| dt.with_timezone(&chrono::Utc)) |
| 482 | + .unwrap_or_else(|_| chrono::Utc::now()), |
| 483 | + level: l.level, |
| 484 | + message: l.message, |
| 485 | + } |
| 486 | + }).collect(); |
| 487 | + |
| 488 | + let queue = state.queue.lock().unwrap(); |
| 489 | + match queue.append_job_logs(&id, logs) { |
| 490 | + Ok(_) => { |
| 491 | + StatusCode::OK.into_response() |
| 492 | + } |
| 493 | + Err(e) => { |
| 494 | + error!("Failed to append job logs: {}", e); |
| 495 | + AppError { |
| 496 | + status: StatusCode::NOT_FOUND, |
| 497 | + message: format!("Job not found: {}", e), |
| 498 | + }.into_response() |
| 499 | + } |
| 500 | + } |
| 501 | +} |
| 502 | + |
459 | 503 | async fn serve_worker_binary() -> Response { |
460 | 504 | // Serve the Linux worker binary from ./assets/worker-linux |
461 | 505 | let path = "./assets/worker-linux"; |
|
0 commit comments