immich-automated-selfie-tim.../src/web/state.rs
2026-01-25 20:01:14 +01:00

95 lines
2.4 KiB
Rust

//! Application state for the web server.
use crate::config::Config;
use std::sync::Arc;
use tokio::sync::{broadcast, RwLock};
use tokio_util::sync::CancellationToken;
/// Job status.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum JobStatus {
Idle,
Running,
CompilingVideo,
Completed,
Cancelled,
Error(String),
}
/// Progress information for a running job.
#[derive(Debug, Clone)]
pub struct Progress {
pub status: JobStatus,
pub completed: u32,
pub total: u32,
pub message: Option<String>,
}
impl Default for Progress {
fn default() -> Self {
Self {
status: JobStatus::Idle,
completed: 0,
total: 0,
message: None,
}
}
}
/// Shared application state.
#[derive(Clone)]
pub struct AppState {
/// Current configuration.
pub config: Arc<RwLock<Config>>,
/// Current job progress.
pub progress: Arc<RwLock<Progress>>,
/// Channel for broadcasting progress updates.
pub progress_tx: broadcast::Sender<Progress>,
/// Cancellation token for the current job.
pub cancel_token: Arc<RwLock<Option<CancellationToken>>>,
}
impl AppState {
pub fn new(config: Config) -> Self {
let (progress_tx, _) = broadcast::channel(100);
Self {
config: Arc::new(RwLock::new(config)),
progress: Arc::new(RwLock::new(Progress::default())),
progress_tx,
cancel_token: Arc::new(RwLock::new(None)),
}
}
/// Update progress and broadcast to all listeners.
pub async fn update_progress(&self, progress: Progress) {
*self.progress.write().await = progress.clone();
let _ = self.progress_tx.send(progress);
}
/// Request cancellation of the current job.
pub async fn request_cancel(&self) -> bool {
let cancel_token = self.cancel_token.read().await;
if let Some(token) = cancel_token.as_ref() {
token.cancel();
true
} else {
false
}
}
/// Create a new cancellation token for a job.
pub async fn create_cancel_token(&self) -> CancellationToken {
let token = CancellationToken::new();
*self.cancel_token.write().await = Some(token.clone());
token
}
/// Clear the cancellation token when job completes.
pub async fn clear_cancel_token(&self) {
*self.cancel_token.write().await = None;
}
}