diff --git a/src/api/client_server/media.rs b/src/api/client_server/media.rs index eb7298e0..8b37adf0 100644 --- a/src/api/client_server/media.rs +++ b/src/api/client_server/media.rs @@ -13,7 +13,6 @@ use { webpage::HTML, reqwest::Url, std::{io::Cursor, net::IpAddr, sync::Arc}, - tokio::sync::Notify, image::io::Reader as ImgReader, }; @@ -198,49 +197,21 @@ async fn get_url_preview(url: &str) -> Result { return Ok(preview); } - let notif_opt = services() - .media - .url_preview_requests - .read() - .unwrap() - .get(url) - .cloned(); + // ensure that only one request is made per URL + let mutex_request = Arc::clone( + services() + .media + .url_preview_mutex + .write() + .unwrap() + .entry(url.to_owned()) + .or_default(), + ); + let _request_lock = mutex_request.lock().await; - match notif_opt { - None => { - let notifier = Arc::new(Notify::new()); - { - services().media - .url_preview_requests - .write() - .unwrap() - .insert(url.to_owned(), notifier.clone()); - } - - let data = request_url_preview(url).await; - - notifier.notify_waiters(); - - { - services().media.url_preview_requests.write().unwrap().remove(url); - } - - data - } - Some(notifier) => { - // wait until being notified that request is finished - let notifier = notifier.clone(); - let notifier = notifier.notified(); - notifier.await; - - services().media - .get_url_preview(url) - .await - .ok_or(Error::BadRequest( - ErrorKind::Unknown, - "No Preview available", - )) - } + match services().media.get_url_preview(url).await { + Some(preview) => Ok(preview), + None => request_url_preview(url).await } } diff --git a/src/service/media/mod.rs b/src/service/media/mod.rs index d94184ca..3b02b919 100644 --- a/src/service/media/mod.rs +++ b/src/service/media/mod.rs @@ -14,7 +14,7 @@ use image::imageops::FilterType; use tokio::{ fs::File, io::{AsyncReadExt, AsyncWriteExt, BufReader}, - sync::Notify, + sync::Mutex, }; use serde::Serialize; @@ -60,7 +60,7 @@ pub struct UrlPreviewData { pub struct Service { pub db: &'static dyn Data, - pub url_preview_requests: RwLock>>, + pub url_preview_mutex: RwLock>>>, } impl Service { diff --git a/src/service/mod.rs b/src/service/mod.rs index 6db8113f..ec6b69a4 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -120,7 +120,7 @@ impl Services { key_backups: key_backups::Service { db }, media: media::Service { db, - url_preview_requests: StdRwLock::new(HashMap::new()) + url_preview_mutex: StdRwLock::new(HashMap::new()), }, sending: sending::Service::build(db, &config),