feat(api): add library sync background task
This commit is contained in:
64
k-tv-backend/api/src/library_scheduler.rs
Normal file
64
k-tv-backend/api/src/library_scheduler.rs
Normal file
@@ -0,0 +1,64 @@
|
||||
//! Background library sync task.
|
||||
//! Fires 10 seconds after startup, then every N hours (read from app_settings).
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use domain::IProviderRegistry;
|
||||
|
||||
const STARTUP_DELAY_SECS: u64 = 10;
|
||||
const DEFAULT_INTERVAL_HOURS: u64 = 6;
|
||||
|
||||
pub async fn run_library_sync(
|
||||
sync_adapter: Arc<dyn domain::LibrarySyncAdapter>,
|
||||
registry: Arc<tokio::sync::RwLock<Arc<infra::ProviderRegistry>>>,
|
||||
app_settings_repo: Arc<dyn domain::IAppSettingsRepository>,
|
||||
) {
|
||||
tokio::time::sleep(Duration::from_secs(STARTUP_DELAY_SECS)).await;
|
||||
|
||||
loop {
|
||||
tick(&sync_adapter, ®istry).await;
|
||||
|
||||
let interval_hours = load_interval_hours(&app_settings_repo).await;
|
||||
tokio::time::sleep(Duration::from_secs(interval_hours * 3600)).await;
|
||||
}
|
||||
}
|
||||
|
||||
async fn load_interval_hours(repo: &Arc<dyn domain::IAppSettingsRepository>) -> u64 {
|
||||
repo.get("library_sync_interval_hours")
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
.and_then(|v| v.parse::<u64>().ok())
|
||||
.unwrap_or(DEFAULT_INTERVAL_HOURS)
|
||||
}
|
||||
|
||||
async fn tick(
|
||||
sync_adapter: &Arc<dyn domain::LibrarySyncAdapter>,
|
||||
registry: &Arc<tokio::sync::RwLock<Arc<infra::ProviderRegistry>>>,
|
||||
) {
|
||||
let reg = registry.read().await;
|
||||
let provider_ids: Vec<String> = reg.provider_ids();
|
||||
drop(reg);
|
||||
|
||||
for provider_id in provider_ids {
|
||||
let reg = registry.read().await;
|
||||
let provider = match reg.get_provider(&provider_id) {
|
||||
Some(p) => p,
|
||||
None => continue,
|
||||
};
|
||||
drop(reg);
|
||||
|
||||
tracing::info!("library-sync: syncing provider '{}'", provider_id);
|
||||
let result = sync_adapter.sync_provider(provider.as_ref(), &provider_id).await;
|
||||
|
||||
if let Some(ref err) = result.error {
|
||||
tracing::warn!("library-sync: provider '{}' failed: {}", provider_id, err);
|
||||
} else {
|
||||
tracing::info!(
|
||||
"library-sync: provider '{}' done — {} items in {}ms",
|
||||
provider_id, result.items_found, result.duration_ms
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user