perf: non-blocking hash + parallel thumbnail generation

- Replace blocking blake3::hash() with DedupService::hash_file() in
  file_upload_service (create_file, update_file). Uses spawn_blocking +
  mmap_rayon instead of blocking the Tokio async worker.
- Parallelize thumbnail resize+encode with rayon par_iter() for the 3
  sizes (Icon, Preview, Large) inside spawn_blocking.
This commit is contained in:
Diocrafts
2026-04-11 19:13:48 +02:00
parent 3dc4e6a68b
commit 63bcd0ffe7
2 changed files with 9 additions and 3 deletions
@@ -8,6 +8,7 @@ use crate::application::services::storage_usage_service::StorageUsageService;
use crate::common::errors::DomainError;
use crate::infrastructure::repositories::pg::FileBlobReadRepository;
use crate::infrastructure::repositories::pg::FileBlobWriteRepository;
use crate::infrastructure::services::dedup_service::DedupService;
use crate::infrastructure::services::file_content_cache::FileContentCache;
use tracing::{debug, info, warn};
@@ -211,7 +212,9 @@ impl FileUploadUseCase for FileUploadService {
tokio::fs::write(temp.path(), content)
.await
.map_err(|e| DomainError::internal_error("FileUpload", format!("write temp: {e}")))?;
let hash = blake3::hash(content).to_hex().to_string();
let hash = DedupService::hash_file(temp.path())
.await
.map_err(|e| DomainError::internal_error("FileUpload", format!("hash: {e}")))?;
let file = self
.file_write
@@ -246,7 +249,9 @@ impl FileUploadUseCase for FileUploadService {
tokio::fs::write(temp.path(), content)
.await
.map_err(|e| DomainError::internal_error("FileUpload", format!("write temp: {e}")))?;
let hash = blake3::hash(content).to_hex().to_string();
let hash = DedupService::hash_file(temp.path())
.await
.map_err(|e| DomainError::internal_error("FileUpload", format!("hash: {e}")))?;
self.update_file_streaming(
path,
@@ -1,6 +1,7 @@
use bytes::Bytes;
use image::codecs::jpeg::JpegEncoder;
use image::imageops::FilterType;
use rayon::prelude::*;
/**
* Thumbnail Generation Service
*
@@ -534,7 +535,7 @@ impl ThumbnailService {
let (orig_w, orig_h) = (img.width(), img.height());
ThumbnailSize::all()
.iter()
.par_iter()
.map(|&size| {
let max_dim = size.max_dimension();