use std::{path::PathBuf, sync::Arc}; use pinakes_core::{ cache::CacheLayer, config::Config, jobs::JobQueue, managed_storage::ManagedStorageService, plugin::{PluginManager, PluginPipeline}, scan::ScanProgress, scheduler::TaskScheduler, storage::DynStorageBackend, sync::ChunkedUploadManager, transcode::TranscodeService, webhooks::WebhookDispatcher, }; use tokio::sync::{RwLock, Semaphore}; // Note: Sessions are now stored in the database via StorageBackend // See storage::SessionData and related methods /// Max concurrent background session operations (touch/delete). /// Prevents unbounded task spawning under high request load. pub const MAX_SESSION_BACKGROUND_TASKS: usize = 64; #[derive(Clone)] pub struct AppState { pub storage: DynStorageBackend, pub config: Arc>, pub config_path: Option, pub scan_progress: ScanProgress, pub job_queue: Arc, pub cache: Arc, pub scheduler: Arc, pub plugin_manager: Option>, pub plugin_pipeline: Option>, pub transcode_service: Option>, pub managed_storage: Option>, pub chunked_upload_manager: Option>, pub webhook_dispatcher: Option>, pub session_semaphore: Arc, } impl AppState { /// Emit a plugin event if the pipeline is active. pub fn emit_plugin_event( &self, event_type: &str, payload: &serde_json::Value, ) { if let Some(ref pipeline) = self.plugin_pipeline { pipeline.emit_event(event_type, payload); } } }