diff --git a/src/controllers/krate/metadata.rs b/src/controllers/krate/metadata.rs index 41c79d6650a..ee0344d5e3f 100644 --- a/src/controllers/krate/metadata.rs +++ b/src/controllers/krate/metadata.rs @@ -249,51 +249,55 @@ pub async fn reverse_dependencies( Path(name): Path, req: Parts, ) -> AppResult> { - let conn = app.db_read().await?; - spawn_blocking(move || { - use diesel::RunQueryDsl; + use diesel_async::RunQueryDsl; - let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into(); + let mut conn = app.db_read().await?; - let pagination_options = PaginationOptions::builder().gather(&req)?; + let pagination_options = PaginationOptions::builder().gather(&req)?; - let krate: Crate = Crate::by_name(&name) - .first(conn) - .optional()? - .ok_or_else(|| crate_not_found(&name))?; + let krate: Crate = Crate::by_name(&name) + .first(&mut conn) + .await + .optional()? + .ok_or_else(|| crate_not_found(&name))?; - let (rev_deps, total) = krate.reverse_dependencies(conn, pagination_options)?; - let rev_deps: Vec<_> = rev_deps - .into_iter() - .map(|dep| EncodableDependency::from_reverse_dep(dep, &krate.name)) - .collect(); + let (rev_deps, total) = krate + .reverse_dependencies(&mut conn, pagination_options) + .await?; - let version_ids: Vec = rev_deps.iter().map(|dep| dep.version_id).collect(); + let rev_deps: Vec<_> = rev_deps + .into_iter() + .map(|dep| EncodableDependency::from_reverse_dep(dep, &krate.name)) + .collect(); - let versions_and_publishers: Vec<(Version, CrateName, Option)> = versions::table - .filter(versions::id.eq_any(version_ids)) - .inner_join(crates::table) - .left_outer_join(users::table) - .select(<(Version, CrateName, Option)>::as_select()) - .load(conn)?; - let versions = versions_and_publishers - .iter() - .map(|(v, ..)| v) - .collect::>(); - let actions = VersionOwnerAction::for_versions(conn, &versions)?; - let versions = versions_and_publishers - .into_iter() - .zip(actions) - .map(|((version, krate_name, published_by), actions)| { - EncodableVersion::from(version, &krate_name.name, published_by, actions) - }) - .collect::>(); + let version_ids: Vec = rev_deps.iter().map(|dep| dep.version_id).collect(); - Ok(Json(json!({ - "dependencies": rev_deps, - "versions": versions, - "meta": { "total": total }, - }))) - }) - .await + let versions_and_publishers: Vec<(Version, CrateName, Option)> = versions::table + .filter(versions::id.eq_any(version_ids)) + .inner_join(crates::table) + .left_outer_join(users::table) + .select(<(Version, CrateName, Option)>::as_select()) + .load(&mut conn) + .await?; + + let versions = versions_and_publishers + .iter() + .map(|(v, ..)| v) + .collect::>(); + + let actions = VersionOwnerAction::async_for_versions(&mut conn, &versions).await?; + + let versions = versions_and_publishers + .into_iter() + .zip(actions) + .map(|((version, krate_name, published_by), actions)| { + EncodableVersion::from(version, &krate_name.name, published_by, actions) + }) + .collect::>(); + + Ok(Json(json!({ + "dependencies": rev_deps, + "versions": versions, + "meta": { "total": total }, + }))) } diff --git a/src/models/action.rs b/src/models/action.rs index 315c5091587..94bc46b1c23 100644 --- a/src/models/action.rs +++ b/src/models/action.rs @@ -4,6 +4,7 @@ use crate::sql::pg_enum; use crate::util::diesel::prelude::*; use crate::util::diesel::Conn; use chrono::NaiveDateTime; +use diesel_async::AsyncPgConnection; pg_enum! { pub enum VersionAction { @@ -78,6 +79,20 @@ impl VersionOwnerAction { .load(conn)? .grouped_by(versions)) } + + pub async fn async_for_versions( + conn: &mut AsyncPgConnection, + versions: &[&Version], + ) -> QueryResult>> { + use diesel_async::RunQueryDsl; + + Ok(Self::belonging_to(versions) + .inner_join(users::table) + .order(version_owner_actions::dsl::id) + .load(conn) + .await? + .grouped_by(versions)) + } } pub fn insert_version_owner_action( diff --git a/src/models/krate.rs b/src/models/krate.rs index 794b0da643f..caa21edca11 100644 --- a/src/models/krate.rs +++ b/src/models/krate.rs @@ -464,14 +464,14 @@ impl Crate { /// Returns (dependency, dependent crate name, dependent crate downloads) #[instrument(skip_all, fields(krate.name = %self.name))] - pub(crate) fn reverse_dependencies( + pub(crate) async fn reverse_dependencies( &self, - conn: &mut impl Conn, + conn: &mut AsyncPgConnection, options: PaginationOptions, ) -> QueryResult<(Vec, i64)> { use diesel::sql_query; use diesel::sql_types::{BigInt, Integer}; - use diesel::RunQueryDsl; + use diesel_async::RunQueryDsl; let offset = options.offset().unwrap_or_default(); let rows: Vec> = @@ -479,7 +479,8 @@ impl Crate { .bind::(self.id) .bind::(offset) .bind::(options.per_page) - .load(conn)?; + .load(conn) + .await?; Ok(rows.records_and_total()) }