From 0a72d5a203a3a52340335a94ca56d6a8cddcda80 Mon Sep 17 00:00:00 2001 From: Michal Vanko Date: Thu, 5 Sep 2024 21:23:28 +0200 Subject: [PATCH] paralellize image generator --- axum_server/Cargo.toml | 1 + axum_server/src/main.rs | 1 + .../src/picture_generator/export_format.rs | 2 +- .../src/picture_generator/image_generator.rs | 5 +-- .../picture_markup_generator.rs | 34 +++++++++++++++---- 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/axum_server/Cargo.toml b/axum_server/Cargo.toml index 0a83d74..03430ca 100644 --- a/axum_server/Cargo.toml +++ b/axum_server/Cargo.toml @@ -22,6 +22,7 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } image = "0.25.2" anyhow = "1.0.86" +rayon = "1.10.0" [build] rustflags = ["-Z", "threads=8"] diff --git a/axum_server/src/main.rs b/axum_server/src/main.rs index 25da31c..b6dc39f 100644 --- a/axum_server/src/main.rs +++ b/axum_server/src/main.rs @@ -31,6 +31,7 @@ async fn main() { let app = router::get_router() .nest_service("/styles", ServeDir::new("styles")) .nest_service("/images", ServeDir::new("../static/images")) + .nest_service("/generated_images", ServeDir::new("generated_images")) .nest_service("/svg", ServeDir::new("../static/svg")) .nest_service( "/config.yml", diff --git a/axum_server/src/picture_generator/export_format.rs b/axum_server/src/picture_generator/export_format.rs index 739f0ba..4d0856e 100644 --- a/axum_server/src/picture_generator/export_format.rs +++ b/axum_server/src/picture_generator/export_format.rs @@ -1,6 +1,6 @@ use image::ImageFormat; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone, Copy)] pub enum ExportFormat { Jpeg, Avif, diff --git a/axum_server/src/picture_generator/image_generator.rs b/axum_server/src/picture_generator/image_generator.rs index 705dd80..aba0519 100644 --- a/axum_server/src/picture_generator/image_generator.rs +++ b/axum_server/src/picture_generator/image_generator.rs @@ -1,6 +1,7 @@ use std::{fs::create_dir_all, path::Path}; use image::{imageops::FilterType, DynamicImage}; +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use tracing::{debug, error}; use super::export_format::ExportFormat; @@ -11,8 +12,8 @@ pub fn generate_images( resolutions: &[(u32, u32, f32)], formats: &[ExportFormat], ) -> Result<(), anyhow::Error> { - formats.iter().for_each(|format| { - resolutions.iter().for_each(|resolution| { + formats.par_iter().for_each(|format| { + resolutions.par_iter().for_each(|resolution| { let (width, height, _) = *resolution; // let image = image.clone(); let resized = image.resize_to_fill(width, height, FilterType::Triangle); diff --git a/axum_server/src/picture_generator/picture_markup_generator.rs b/axum_server/src/picture_generator/picture_markup_generator.rs index 0f855b9..82218f4 100644 --- a/axum_server/src/picture_generator/picture_markup_generator.rs +++ b/axum_server/src/picture_generator/picture_markup_generator.rs @@ -2,6 +2,7 @@ use std::{ cmp::Ordering, path::{Path, PathBuf}, str::FromStr as _, + sync::Arc, }; use anyhow::Context; @@ -30,13 +31,32 @@ pub fn generate_picture_markup( let resolutions = get_resolutions(orig_img_dimensions, width, height); // TODO lets generate images - generate_images( - &orig_img, - &path_to_generated, - &resolutions, - &exported_formats, - ) - .with_context(|| "Failed to generate images".to_string())?; + + let orig_img_arc = Arc::new(orig_img); + let orig_img_clone = Arc::clone(&orig_img_arc); + let path_to_generated_arc = Arc::new(path_to_generated); + let path_to_generated_clone = Arc::clone(&path_to_generated_arc); + let resolutions_arc = Arc::new(resolutions); + let resolutions_clone = Arc::clone(&resolutions_arc); + let exported_formats_arc = Arc::new(exported_formats); + let exported_formats_clone = Arc::clone(&exported_formats_arc); + + tokio::spawn(async move { + let orig_img = orig_img_clone.as_ref(); + let path_to_generated = path_to_generated_clone.as_ref(); + let resolutions = resolutions_clone.as_ref(); + let exported_formats = exported_formats_clone.as_ref(); + + let result = generate_images(orig_img, path_to_generated, resolutions, exported_formats) + .with_context(|| "Failed to generate images".to_string()); + if let Err(e) = result { + tracing::error!("Error: {}", e); + } + }); + + let exported_formats = Arc::clone(&exported_formats_arc); + let path_to_generated = Arc::clone(&path_to_generated_arc); + let resolutions = Arc::clone(&resolutions_arc); let source_tags = exported_formats .iter()