From e203815f4f875b02e192277948c2bd9726602e01 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 29 Mar 2018 13:07:46 +0300 Subject: [PATCH] hammond-gtk/utils.rs: Use a hashset to keep track of cover downloads. Use a HashSet to check if a download of a cover is already active. If it is, schedule a callback that will try to set the image from the cached pixbuf later. --- hammond-gtk/src/utils.rs | 44 +++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index fb471bf..76efbcd 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -133,7 +133,11 @@ fn refresh_feed(source: Option>, sender: Sender) -> Result<( lazy_static! { static ref CACHED_PIXBUFS: RwLock>>> = { RwLock::new(HashMap::new()) }; - static ref THREADPOOL: rayon::ThreadPool = rayon::ThreadPoolBuilder::new().build().unwrap(); + static ref COVER_DL_REGISTRY: RwLock> = RwLock::new(HashSet::new()); + static ref THREADPOOL: rayon::ThreadPool = rayon::ThreadPoolBuilder::new() + .breadth_first() + .build() + .unwrap(); } // Since gdk_pixbuf::Pixbuf is refference counted and every episode, @@ -148,6 +152,26 @@ pub fn set_image_from_path( pd: Arc, size: u32, ) -> Result<(), Error> { + { + // Check if there's an active download about this show cover. + // If there is, a callback will be set so this function will be called again. + // If the download succedes, there should be a quick return from the pixbuf cache_image + // If it fails another download will be scheduled. + let reg_guard = COVER_DL_REGISTRY + .read() + .map_err(|err| format_err!("Cover Registry: {}.", err))?; + if reg_guard.contains(&pd.id()) { + gtk::timeout_add( + 250, + clone!(image, pd => move || { + let _ = set_image_from_path(&image, pd.clone(), size); + glib::Continue(false) + }), + ); + return Ok(()); + } + } + { let hashmap = CACHED_PIXBUFS .read() @@ -164,12 +188,22 @@ pub fn set_image_from_path( let (sender, receiver) = channel(); let pd_ = pd.clone(); THREADPOOL.spawn(move || { - sender.send(downloader::cache_image(&pd_)).unwrap(); + { + if let Ok(mut guard) = COVER_DL_REGISTRY.write() { + guard.insert(pd_.id()); + } + } + let _ = sender.send(downloader::cache_image(&pd_)); + { + if let Ok(mut guard) = COVER_DL_REGISTRY.write() { + guard.remove(&pd_.id()); + } + } }); let image = image.clone(); let s = size as i32; - gtk::timeout_add(50, move || { + gtk::timeout_add(25, move || { if let Ok(path) = receiver.try_recv() { if let Ok(path) = path { if let Ok(px) = Pixbuf::new_from_file_at_scale(&path, s, s, true) { @@ -229,8 +263,8 @@ pub fn time_period_to_duration(time: i64, period: &str) -> Duration { #[cfg(test)] mod tests { use super::*; - use hammond_data::Source; - use hammond_data::dbqueries; + // use hammond_data::Source; + // use hammond_data::dbqueries; #[test] fn test_time_period_to_duration() {