diff --git a/Cargo.lock b/Cargo.lock index e8e4227..a4c5526 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -588,6 +588,7 @@ dependencies = [ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "loggerv 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/hammond-data/src/index_feed.rs b/hammond-data/src/index_feed.rs index 7e5ea1b..2ddb778 100644 --- a/hammond-data/src/index_feed.rs +++ b/hammond-data/src/index_feed.rs @@ -89,9 +89,15 @@ fn insert_return_episode(con: &SqliteConnection, ep: &NewEpisode) -> Result Result<()> { +pub fn full_index_loop(db: &Database) -> Result<()> { let mut f = fetch_feeds(db)?; + index_feed(&db, &mut f); + info!("Indexing done."); + Ok(()) +} + +pub fn index_feed(db: &Database, f: &mut [Feed]) { f.par_iter_mut() .for_each(|&mut Feed(ref mut req, ref source)| { let e = complete_index_from_source(req, source, db); @@ -100,8 +106,6 @@ pub fn index_loop(db: &Database) -> Result<()> { error!("Error msg: {}", e.unwrap_err()); }; }); - info!("Indexing done."); - Ok(()) } pub fn complete_index_from_source( @@ -274,10 +278,10 @@ mod tests { index_source(&tempdb, &NewSource::new_with_uri(feed)).unwrap() }); - index_loop(&db).unwrap(); + full_index_loop(&db).unwrap(); // Run again to cover Unique constrains erros. - index_loop(&db).unwrap(); + full_index_loop(&db).unwrap(); } #[test] diff --git a/hammond-gtk/Cargo.toml b/hammond-gtk/Cargo.toml index 685f9d1..088848f 100644 --- a/hammond-gtk/Cargo.toml +++ b/hammond-gtk/Cargo.toml @@ -15,6 +15,7 @@ loggerv = "0.4" log = "0.3" open = "1.2" dissolve = "0.2" +rayon = "0.8" hammond-data = {path = "../hammond-data"} hammond-downloader = {path = "../hammond-downloader"} diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index af44f9f..da07c7c 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -49,7 +49,7 @@ pub fn get_headerbar(db: &Database, stack: >k::Stack) -> gtk::HeaderBar { // FIXME: There appears to be a memmory leak here. refresh_button.connect_clicked(clone!(stack, db => move |_| { - utils::refresh_db(&db, &stack); + utils::refresh_feed(&db, &stack, None); })); header @@ -62,9 +62,9 @@ fn on_add_bttn_clicked(db: &Database, stack: >k::Stack, url: &str) { }; info!("{:?} feed added", url); - if let Ok(mut s) = source { + if let Ok(s) = source { // update the db - utils::refresh_feed(db, stack, &mut s); + utils::refresh_feed(db, stack, Some(Box::new(vec![s]))); } else { error!("Expected Error, feed probably already exists."); error!("Error: {:?}", source.unwrap_err()); diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 78b1950..670e4da 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -12,6 +12,7 @@ extern crate hammond_downloader; extern crate log; extern crate loggerv; extern crate open; +extern crate rayon; use log::LogLevel; use hammond_data::dbcheckup; diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index cdd6067..bfc7575 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -1,9 +1,8 @@ use glib; use gtk; -// use gtk::prelude::*; +use rayon::prelude::*; -use hammond_data; -use hammond_data::index_feed::Feed; +use hammond_data::index_feed; use hammond_data::models::Source; use hammond_data::index_feed::Database; @@ -19,48 +18,31 @@ thread_local!( gtk::Stack, Receiver)>> = RefCell::new(None)); -pub fn refresh_db(db: &Database, stack: >k::Stack) { - // Create a async channel. +pub fn refresh_feed(db: &Database, stack: >k::Stack, source: Option>>) { let (sender, receiver) = channel(); - // Pass the desired arguments into the Local Thread Storage. GLOBAL.with(clone!(db, stack => move |global| { *global.borrow_mut() = Some((db, stack, receiver)); })); - // The implementation of how this is done is probably terrible but it works!. // TODO: add timeout option and error reporting. thread::spawn(clone!(db => move || { - let t = hammond_data::index_feed::index_loop(&db); - if t.is_err() { - error!("Error While trying to update the database."); - error!("Error msg: {}", t.unwrap_err()); + let feeds = { + if let Some(mut boxed_vec) = source { + let f = boxed_vec + .par_iter_mut() + .filter_map(|mut s| { + index_feed::refresh_source(&db, &mut s).ok() + }) + .collect(); + Ok(f) + } else { + index_feed::fetch_feeds(&db) + } }; - sender.send(true).expect("Couldn't send data to channel");; - // http://gtk-rs.org/docs/glib/source/fn.idle_add.html - glib::idle_add(refresh_podcasts_view); - })); -} - -pub fn refresh_feed(db: &Database, stack: >k::Stack, source: &mut Source) { - let (sender, receiver) = channel(); - - GLOBAL.with(clone!(db, stack => move |global| { - *global.borrow_mut() = Some((db, stack, receiver)); - })); - - // TODO: add timeout option and error reporting. - thread::spawn(clone!(db, source => move || { - let foo_ = hammond_data::index_feed::refresh_source(&db, &mut source.clone()); - - if let Ok(x) = foo_ { - let Feed(mut req, s) = x; - let s = hammond_data::index_feed::complete_index_from_source(&mut req, &s, &db); - if s.is_err() { - error!("Error While trying to update the database."); - error!("Error msg: {}", s.unwrap_err()); - }; + if let Ok(mut x) = feeds { + index_feed::index_feed(&db, &mut x); sender.send(true).expect("Couldn't send data to channel");; glib::idle_add(refresh_podcasts_view); diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index a2b79bb..7882b02 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -199,7 +199,7 @@ fn receive() -> glib::Continue { pub fn episodes_listbox(db: &Database, pd: &Podcast) -> Result { let conn = db.lock().unwrap(); - let mut episodes = dbqueries::get_pd_episodes(&conn, &pd)?; + let mut episodes = dbqueries::get_pd_episodes(&conn, pd)?; drop(conn); let list = gtk::ListBox::new(); diff --git a/hammond-gtk/src/widgets/podcast.rs b/hammond-gtk/src/widgets/podcast.rs index dbc4c1d..ef070fe 100644 --- a/hammond-gtk/src/widgets/podcast.rs +++ b/hammond-gtk/src/widgets/podcast.rs @@ -30,7 +30,7 @@ fn podcast_widget(db: &Database, stack: >k::Stack, pd: &Podcast) -> gtk::Box { })); title_label.set_text(pd.title()); - let listbox = episodes_listbox(db, &pd); + let listbox = episodes_listbox(db, pd); if let Ok(l) = listbox { view.add(&l); }