diff options
Diffstat (limited to 'front_end/src/crate_page.rs')
-rw-r--r-- | front_end/src/crate_page.rs | 77 |
1 files changed, 43 insertions, 34 deletions
diff --git a/front_end/src/crate_page.rs b/front_end/src/crate_page.rs index 2fdf934..370f6c2 100644 --- a/front_end/src/crate_page.rs +++ b/front_end/src/crate_page.rs @@ -1,3 +1,4 @@ +use futures::future::Future; use tokio::runtime::Handle; use futures::future::join_all; use crate::download_graph::DownloadsGraph; @@ -105,14 +106,13 @@ impl<'a> CratePage<'a> { .and_then(|(top, slug)| CATEGORIES.from_slug(slug).last().map(|c| (top, c))); let is_build_or_dev = kitchen_sink.is_build_or_dev(ver.origin()).await?; - let (top_keyword, (all_contributors, deps)) = rayon::join( - || kitchen_sink.top_keyword(all), - || rayon::join( - || kitchen_sink.all_contributors(ver), - || kitchen_sink.all_dependencies_flattened(ver))); + let (top_keyword, all_contributors) = futures::try_join!( + kitchen_sink.top_keyword(all), + kitchen_sink.all_contributors(ver))?; + let deps = kitchen_sink.all_dependencies_flattened(ver); let mut page = Self { - top_keyword: top_keyword?, - all_contributors: all_contributors?, + top_keyword, + all_contributors, all, ver, kitchen_sink, @@ -185,7 +185,7 @@ impl<'a> CratePage<'a> { } pub fn changelog_url(&self) -> Option<String> { - self.kitchen_sink.changelog_url(self.ver) + self.handle.enter(|| futures::executor::block_on(self.kitchen_sink.changelog_url(self.ver))) } pub fn is_build_or_dev(&self) -> (bool, bool) { @@ -206,18 +206,22 @@ impl<'a> CratePage<'a> { /// If true, there are many other crates with this keyword. Populated first. pub fn keywords_populated(&self) -> Option<Vec<(String, bool)>> { - let k = self.kitchen_sink.keywords_populated(self.ver); - if k.is_empty() { - None - } else { - Some(k) - } + self.handle.enter(|| futures::executor::block_on(async { + let k = self.kitchen_sink.keywords_populated(self.ver).await; + if k.is_empty() { + None + } else { + Some(k) + } + })) } pub fn parent_crate(&self) -> Option<RichCrateVersion> { - let origin = self.kitchen_sink.parent_crate(self.ver)?; - self.kitchen_sink.rich_crate_version(&origin) - .map_err(|e| eprintln!("parent crate: {} {:?}", e, origin)).ok() + self.handle.enter(|| futures::executor::block_on(async { + let origin = self.kitchen_sink.parent_crate(self.ver).await?; + self.kitchen_sink.rich_crate_version(&origin) + .map_err(|e| eprintln!("parent crate: {} {:?}", e, origin)).ok() + })) } pub fn render_markdown_str(&self, s: &str) -> templates::Html<String> { @@ -259,7 +263,11 @@ impl<'a> CratePage<'a> { pub fn nofollow(&self) -> bool { // TODO: take multiple factors into account, like # of contributors, author reputation, dependents - self.kitchen_sink.downloads_per_month_or_equivalent(self.all.origin()).ok().and_then(|x| x).unwrap_or(0) < 50 + self.block(self.kitchen_sink.downloads_per_month_or_equivalent(self.all.origin())).ok().and_then(|x| x).unwrap_or(0) < 50 + } + + fn block<O>(&self, f: impl Future<Output=O>) -> O { + self.handle.enter(|| futures::executor::block_on(f)) } pub(crate) fn all_contributors(&self) -> Contributors<'_> { @@ -355,22 +363,21 @@ impl<'a> CratePage<'a> { } pub fn up_to_date_class(&self, richdep: &RichDep) -> &str { - if richdep.dep.req() == "*" { + if richdep.dep.req() == "*" || !richdep.dep.is_crates_io() { return "common"; } - self.handle.enter(|| { - let (matches_latest, pop) = richdep.dep.req().parse().ok().and_then(|req| { - if !richdep.dep.is_crates_io() { - return None; + self.block(async { + if let Ok(req) = richdep.dep.req().parse() { + if let Ok(Some((matches_latest, pop))) = self.kitchen_sink.version_popularity(&richdep.package, &req).await { + return match pop { + x if x >= 0.5 && matches_latest => "top", + x if x >= 0.75 || matches_latest => "common", + x if x >= 0.25 => "outdated", + _ => "obsolete", + } } - futures::executor::block_on(self.kitchen_sink.version_popularity(&richdep.package, &req)).expect("deps") - }).unwrap_or((false, 0.)); - match pop { - x if x >= 0.5 && matches_latest => "top", - x if x >= 0.75 || matches_latest => "common", - x if x >= 0.25 => "outdated", - _ => "obsolete", } + "obsolete" }) } @@ -675,16 +682,18 @@ impl<'a> CratePage<'a> { } pub fn github_stargazers_and_watchers(&self) -> Option<(u32, u32)> { - self.kitchen_sink.github_stargazers_and_watchers(self.all.origin()).ok().and_then(|x| x) + self.block(self.kitchen_sink.github_stargazers_and_watchers(self.all.origin())).ok().and_then(|x| x) } pub fn related_crates(&self) -> Option<Vec<Origin>> { // require some level of downloads to avoid recommending spam // but limit should be relative to the current crate, so that minor crates // get related suggestions too - let dl = self.kitchen_sink.downloads_per_month_or_equivalent(self.all.origin()).ok().and_then(|x| x).unwrap_or(100); - let min_recent_downloads = (dl as u32/2).min(200); - self.kitchen_sink.related_crates(&self.ver, min_recent_downloads).map_err(|e| eprintln!("related crates fail: {}", e)).ok() + self.block(async { + let dl = self.kitchen_sink.downloads_per_month_or_equivalent(self.all.origin()).await.ok().and_then(|x| x).unwrap_or(100); + let min_recent_downloads = (dl as u32/2).min(200); + self.kitchen_sink.related_crates(&self.ver, min_recent_downloads).await.map_err(|e| eprintln!("related crates fail: {}", e)).ok() + }) } /// data for piechart |