spacedrive/core/examples/pause_resume_demo.rs
2025-10-11 13:14:01 -07:00

152 lines
4.0 KiB
Rust

//! Demonstration of job pause/resume functionality
use sd_core::{
infra::{
db::entities,
job::types::{JobId, JobStatus},
},
location::{create_location, IndexMode, LocationCreateArgs},
Core,
};
use sea_orm::{ActiveModelTrait, EntityTrait};
use std::time::Duration;
use tempfile::TempDir;
use tokio::time::sleep;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize logging
tracing_subscriber::fmt::init();
println!("=== Job Pause/Resume Demo ===\n");
// Setup test environment
let temp_dir = TempDir::new()?;
let core = Core::new(temp_dir.path().to_path_buf()).await?;
// Create library
println!("1. Creating library...");
let library = core
.libraries
.create_library("Demo Library", None, core.context.clone())
.await?;
// Create test location with files
let test_location = temp_dir.path().join("test_location");
tokio::fs::create_dir_all(&test_location).await?;
println!("2. Creating test files...");
for i in 0..50 {
let file_path = test_location.join(format!("test_file_{}.txt", i));
tokio::fs::write(&file_path, format!("Test content {}", i)).await?;
}
// Register device
let db = library.db();
let device = core.device.to_device()?;
let device_model: entities::device::ActiveModel = device.into();
let device_record = device_model.insert(db.conn()).await?;
// Create location to trigger indexing
println!("3. Creating location and starting indexing job...");
let location_args = LocationCreateArgs {
path: test_location.clone(),
name: Some("Demo Location".to_string()),
index_mode: IndexMode::Deep,
};
create_location(
library.clone(),
&core.events,
location_args,
device_record.id,
)
.await?;
// Get the indexing job
let job_manager = library.jobs();
sleep(Duration::from_millis(200)).await;
let running_jobs = job_manager.list_jobs(Some(JobStatus::Running)).await?;
if running_jobs.is_empty() {
println!("No running jobs found!");
return Ok(());
}
let job_info = &running_jobs[0];
let job_id = JobId(job_info.id);
println!(" Found indexing job: {} ({})", job_info.name, job_id.0);
// Let it run for a bit
println!("\n4. Letting job run for 1 second...");
sleep(Duration::from_secs(1)).await;
// Check progress
let job_info = job_manager.get_job_info(job_id.0).await?.unwrap();
println!(" Progress: {:.1}%", job_info.progress);
// Pause the job
println!("\n5. Pausing the job...");
job_manager.pause_job(job_id).await?;
sleep(Duration::from_millis(200)).await;
let job_info = job_manager.get_job_info(job_id.0).await?.unwrap();
println!(" Job status: {:?}", job_info.status);
println!(" Progress when paused: {:.1}%", job_info.progress);
// Wait while paused
println!("\n6. Waiting 2 seconds while paused...");
sleep(Duration::from_secs(2)).await;
let job_info_after_wait = job_manager.get_job_info(job_id.0).await?.unwrap();
println!(
" Progress after waiting: {:.1}% (should be same)",
job_info_after_wait.progress
);
assert_eq!(
job_info.progress, job_info_after_wait.progress,
"Progress should not change while paused"
);
// Resume the job
println!("\n7. Resuming the job...");
job_manager.resume_job(job_id).await?;
// Monitor until completion
println!("\n8. Waiting for job to complete...");
let mut last_progress = job_info_after_wait.progress;
loop {
sleep(Duration::from_millis(500)).await;
let job_info = job_manager.get_job_info(job_id.0).await?.unwrap();
if job_info.progress != last_progress {
println!(" Progress: {:.1}%", job_info.progress);
last_progress = job_info.progress;
}
match job_info.status {
JobStatus::Completed => {
println!("\nJob completed successfully!");
break;
}
JobStatus::Failed => {
println!("\nJob failed: {:?}", job_info.error_message);
break;
}
_ => continue,
}
}
// Check results
use sea_orm::PaginatorTrait;
let indexed_count = entities::entry::Entity::find().count(db.conn()).await?;
println!("\n9. Results:");
println!(" Files indexed: {}", indexed_count);
println!(" Expected: 50");
println!("\nDemo completed successfully!");
Ok(())
}