From 050e40c03900827057ab5db2f6bbe971a6408fda Mon Sep 17 00:00:00 2001 From: "Adam T. Carpenter" Date: Sat, 31 Oct 2020 10:44:31 -0400 Subject: blocking on photo set generation since it hits the fs --- dichroism/src/error.rs | 16 ++++++++++++++-- dichroism/src/handlers.rs | 21 +++++++++++++-------- dichroism/src/image_service.rs | 18 ++++++++++-------- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/dichroism/src/error.rs b/dichroism/src/error.rs index 62333d0..0cdd269 100644 --- a/dichroism/src/error.rs +++ b/dichroism/src/error.rs @@ -1,7 +1,7 @@ #[derive(Debug)] pub enum DichroismError { - UriDataExtract, - ImageWrite, + UriDataExtract(String), + ImageWrite(String), } impl std::error::Error for DichroismError {} @@ -11,3 +11,15 @@ impl std::fmt::Display for DichroismError { write!(f, "{}", self) } } + +impl From for DichroismError { + fn from(e: image::ImageError) -> Self { + Self::ImageWrite(e.to_string()) + } +} + +impl From for DichroismError { + fn from(e: base64::DecodeError) -> Self { + Self::UriDataExtract(e.to_string()) + } +} diff --git a/dichroism/src/handlers.rs b/dichroism/src/handlers.rs index 7c1d302..0480abf 100644 --- a/dichroism/src/handlers.rs +++ b/dichroism/src/handlers.rs @@ -43,10 +43,12 @@ async fn patch_product( if let Some(data_uri) = patch.photo_data { // create new photo_set - let photo_set = image_service::generate_photo_set(&data_uri).map_err(|e| { - eprintln!("{}", e.to_string()); - HttpResponse::InternalServerError().body(e.to_string()) - })?; + let photo_set = web::block(move || image_service::generate_photo_set(&data_uri)) + .await + .map_err(|e| { + eprintln!("{}", e.to_string()); + HttpResponse::InternalServerError().body(e.to_string()) + })?; let conn = pool.get().map_err(to_internal_error)?; let photo_set = web::block(move || repo::store_photo_set(&conn, photo_set)) .await @@ -79,10 +81,13 @@ async fn post_product( let post = post.into_inner(); // create new photo_set - let photo_set = image_service::generate_photo_set(&post.photo_data).map_err(|e| { - eprintln!("{}", e.to_string()); - HttpResponse::InternalServerError().body(e.to_string()) - })?; + let data_uri = post.photo_data; + let photo_set = web::block(move || image_service::generate_photo_set(&data_uri)) + .await + .map_err(|e| { + eprintln!("{}", e.to_string()); + HttpResponse::InternalServerError().body(e.to_string()) + })?; let conn = pool.get().map_err(to_internal_error)?; let photo_set = web::block(move || repo::store_photo_set(&conn, photo_set)) .await diff --git a/dichroism/src/image_service.rs b/dichroism/src/image_service.rs index b33d5c8..3a31e04 100644 --- a/dichroism/src/image_service.rs +++ b/dichroism/src/image_service.rs @@ -2,7 +2,6 @@ use crate::config::CONFIG_INSTANCE; use crate::constants::{PHOTO_BASE_XY, PHOTO_FULLSIZE_XY, PHOTO_THUMBNAIL_XY}; use crate::error::DichroismError; use crate::models::{Photo, PhotoSet}; -use crate::result::Result; use base64::decode; use image::imageops::FilterType; use image::DynamicImage; @@ -17,13 +16,12 @@ static DATA_URI_RE: Lazy = Lazy::new(|| { .expect("Couldn't parse data URI Regex.") }); -// TODO: should be async so server threads don't block on FS access -pub fn generate_photo_set(uri: &str) -> Result { +pub fn generate_photo_set(uri: &str) -> Result { let data = DATA_URI_RE .captures(uri) - .ok_or(DichroismError::UriDataExtract)? + .ok_or_else(|| DichroismError::UriDataExtract("Failed to parse URI".to_string()))? .name("data") - .ok_or(DichroismError::UriDataExtract)? + .ok_or_else(|| DichroismError::UriDataExtract("Failed to extract data".to_string()))? .as_str(); let original = image::load_from_memory(&decode(data)?)?; let fullsize = original.resize(PHOTO_FULLSIZE_XY, PHOTO_FULLSIZE_XY, FilterType::Lanczos3); @@ -48,7 +46,7 @@ pub fn generate_photo_set(uri: &str) -> Result { }) } -pub fn generate_photo(image: &DynamicImage) -> Result { +fn generate_photo(image: &DynamicImage) -> Result { let base_name = Uuid::new_v3(&Uuid::NAMESPACE_OID, &image.to_bytes()) .to_hyphenated() .to_string(); @@ -59,8 +57,12 @@ pub fn generate_photo(image: &DynamicImage) -> Result { let id = path .file_name() - .ok_or(DichroismError::ImageWrite)? + .ok_or_else(|| { + DichroismError::ImageWrite("Error extracting filename from path".to_string()) + })? .to_str() - .ok_or(DichroismError::ImageWrite)?; + .ok_or_else(|| { + DichroismError::ImageWrite("Error converting filename to slice".to_string()) + })?; Ok(Photo::new(String::from(id))) } -- cgit v1.2.3