2026-07-24 19:52:39 +07:00
|
|
|
use std::path::Path;
|
|
|
|
|
|
2026-07-24 13:10:59 +07:00
|
|
|
use crate::config::WorkerConfig;
|
2026-07-24 19:52:39 +07:00
|
|
|
use crate::nats::progress::ProgressReporter;
|
|
|
|
|
use tools_common::types::{Job, JobStatus, Tool};
|
|
|
|
|
|
|
|
|
|
mod compress;
|
|
|
|
|
mod convert;
|
|
|
|
|
mod resize;
|
2026-07-24 13:10:59 +07:00
|
|
|
|
|
|
|
|
/// Process an image tool job.
|
|
|
|
|
pub async fn process_job(
|
|
|
|
|
job: Job,
|
2026-07-24 19:52:39 +07:00
|
|
|
redis: &redis::Client,
|
|
|
|
|
config: &WorkerConfig,
|
2026-07-24 13:10:59 +07:00
|
|
|
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
2026-07-24 19:52:39 +07:00
|
|
|
tracing::info!(job_id = %job.id, tool = %job.tool.as_str(), "Processing image job");
|
|
|
|
|
|
|
|
|
|
let nats = async_nats::connect(&config.nats_url).await?;
|
|
|
|
|
let progress = ProgressReporter::new(redis.clone(), nats, job.id, job.tool.clone());
|
|
|
|
|
|
|
|
|
|
progress
|
|
|
|
|
.report(JobStatus::Processing { stage: "load".to_string(), progress: 10 }, "load", 10, "Memuat gambar...")
|
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
|
|
let input_path = Path::new(&job.file_path);
|
|
|
|
|
let img = image::open(input_path)
|
|
|
|
|
.map_err(|e| format!("Failed to load image: {}", e))?;
|
|
|
|
|
|
|
|
|
|
progress
|
|
|
|
|
.report(JobStatus::Processing { stage: "process".to_string(), progress: 50 }, "process", 50, "Memproses...")
|
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
|
|
let output_dir = config.storage_path.join("output");
|
|
|
|
|
tokio::fs::create_dir_all(&output_dir).await?;
|
|
|
|
|
|
|
|
|
|
let result_path = match job.tool {
|
|
|
|
|
Tool::ImageCompress => compress::process(&img, &job.options, &output_dir, &progress).await?,
|
|
|
|
|
Tool::ImageResize => resize::process(&img, &job.options, &output_dir, &progress).await?,
|
|
|
|
|
Tool::ImageConvert => convert::process(&img, &job.options, &output_dir, &progress).await?,
|
|
|
|
|
_ => {
|
|
|
|
|
// Fallback: save as-is
|
|
|
|
|
let output_path = output_dir.join(format!("{}.png", job.id));
|
|
|
|
|
img.save(&output_path)?;
|
|
|
|
|
output_path
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
progress
|
|
|
|
|
.report(JobStatus::Completed, "complete", 100, "Selesai")
|
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
|
|
// Update Redis with result
|
|
|
|
|
let mut conn = redis.get_multiplexed_async_connection().await?;
|
|
|
|
|
crate::nats::consumer::JobConsumer::update_job_result(
|
|
|
|
|
&mut conn,
|
|
|
|
|
job.id,
|
|
|
|
|
&result_path.to_string_lossy(),
|
|
|
|
|
job.ttl_seconds,
|
|
|
|
|
)
|
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
|
|
tracing::info!(job_id = %job.id, output = %result_path.display(), "Image job completed");
|
2026-07-24 13:10:59 +07:00
|
|
|
Ok(())
|
|
|
|
|
}
|