feat: Add transcription worker and state management
Introduce an `AppState` struct to hold shared application state, including configuration and the transcription sender. Modify `create_router` and `create_router_with_state` to use `AppState`. Update `main.rs` to initialize the transcription worker and pass the `AppState` to the router. Implement the transcription worker logic in `server/src/transcribe/worker.rs`, handling job queues, FFmpeg remuxing, and Whisper transcription. Update `server/src/auth.rs` to use `Arc<Config>` from the shared state. Modify `server/src/routes/upload.rs` to enqueue transcription jobs and handle potential errors. Add `TranscribeJob` and channel types in `server/src/transcribe/mod.rs`.
This commit is contained in:
@@ -3,14 +3,12 @@ mod health;
|
||||
mod upload;
|
||||
mod web;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::routing::{get, post};
|
||||
use axum::Router;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::AppState;
|
||||
|
||||
pub fn api_router() -> Router<Arc<Config>> {
|
||||
pub fn api_router() -> Router<AppState> {
|
||||
Router::new()
|
||||
.route("/api/health", get(health::handle_health))
|
||||
.route("/api/debug/whoami", get(debug::handle_whoami))
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use axum::extract::Multipart;
|
||||
use axum::extract::{Multipart, State};
|
||||
use axum::Json;
|
||||
use tracing::info;
|
||||
use tokio::sync::mpsc::error::TrySendError;
|
||||
use tracing::{info, warn};
|
||||
|
||||
use crate::auth::AuthenticatedUser;
|
||||
use crate::error::AppError;
|
||||
use crate::models::{AckResponse, AckStatus};
|
||||
use crate::transcribe::{TranscribeJob, TranscribeSender};
|
||||
|
||||
pub async fn handle_upload(
|
||||
user: AuthenticatedUser,
|
||||
State(transcribe_tx): State<TranscribeSender>,
|
||||
mut multipart: Multipart,
|
||||
) -> Result<Json<AckResponse>, AppError> {
|
||||
let mut case_id: Option<String> = None;
|
||||
@@ -81,6 +84,18 @@ pub async fn handle_upload(
|
||||
"Recording received"
|
||||
);
|
||||
|
||||
// Enqueue transcription. Failure here is non-fatal: on restart the recovery
|
||||
// scan will re-enqueue any .m4a without a .transcript.txt sibling.
|
||||
match transcribe_tx.try_send(TranscribeJob { audio_path: file_path.clone() }) {
|
||||
Ok(()) => {}
|
||||
Err(TrySendError::Full(_)) => {
|
||||
warn!(file = %file_path.display(), "Transcription queue full; will be picked up on restart");
|
||||
}
|
||||
Err(TrySendError::Closed(_)) => {
|
||||
warn!(file = %file_path.display(), "Transcription queue closed (no worker)");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Json(AckResponse {
|
||||
case_id,
|
||||
recorded_at,
|
||||
|
||||
Reference in New Issue
Block a user