From 1f39fcc2475675679420186f76887507e3da3e19 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Thu, 7 Nov 2024 15:55:27 +0100 Subject: [PATCH] models/version: Convert `record_readme_rendering()` to async fn ... which allows us to remove a `spawn_blocking()` call from the `RenderAndUploadReadme` background job :) --- src/bin/crates-admin/render_readmes.rs | 3 ++- src/models/version.rs | 9 +++++++-- src/tests/version.rs | 9 +++++++-- src/worker/jobs/readmes.rs | 24 ++++++++++++------------ 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/bin/crates-admin/render_readmes.rs b/src/bin/crates-admin/render_readmes.rs index e5e1e1fd394..24122040ae7 100644 --- a/src/bin/crates-admin/render_readmes.rs +++ b/src/bin/crates-admin/render_readmes.rs @@ -115,7 +115,8 @@ pub async fn run(opts: Opts) -> anyhow::Result<()> { let mut tasks = Vec::with_capacity(page_size); for (version, krate_name) in versions { - Version::record_readme_rendering(version.id, &mut conn) + Handle::current() + .block_on(Version::record_readme_rendering(version.id, &mut conn)) .context("Couldn't record rendering time")?; let client = client.clone(); diff --git a/src/models/version.rs b/src/models/version.rs index be7dd438f4b..eaedf41e7ef 100644 --- a/src/models/version.rs +++ b/src/models/version.rs @@ -3,6 +3,7 @@ use std::collections::BTreeMap; use bon::Builder; use chrono::NaiveDateTime; use crates_io_index::features::FeaturesMap; +use diesel_async::AsyncPgConnection; use serde::Deserialize; use crate::models::{Crate, User}; @@ -35,9 +36,12 @@ pub struct Version { } impl Version { - pub fn record_readme_rendering(version_id: i32, conn: &mut impl Conn) -> QueryResult { + pub async fn record_readme_rendering( + version_id: i32, + conn: &mut AsyncPgConnection, + ) -> QueryResult { use diesel::dsl::now; - use diesel::RunQueryDsl; + use diesel_async::RunQueryDsl; diesel::insert_into(readme_renderings::table) .values(readme_renderings::version_id.eq(version_id)) @@ -45,6 +49,7 @@ impl Version { .do_update() .set(readme_renderings::rendered_at.eq(now)) .execute(conn) + .await } /// Gets the User who ran `cargo publish` for this version, if recorded. diff --git a/src/tests/version.rs b/src/tests/version.rs index c2a39f7fcbc..b8b385ae557 100644 --- a/src/tests/version.rs +++ b/src/tests/version.rs @@ -11,6 +11,11 @@ async fn record_rerendered_readme_time() { let c = CrateBuilder::new("foo_authors", user.id).expect_build(&mut conn); let version = VersionBuilder::new("1.0.0").expect_build(c.id, user.id, &mut conn); - Version::record_readme_rendering(version.id, &mut conn).unwrap(); - Version::record_readme_rendering(version.id, &mut conn).unwrap(); + let mut conn = app.async_db_conn().await; + Version::record_readme_rendering(version.id, &mut conn) + .await + .unwrap(); + Version::record_readme_rendering(version.id, &mut conn) + .await + .unwrap(); } diff --git a/src/worker/jobs/readmes.rs b/src/worker/jobs/readmes.rs index be8cb367ee9..8650b8d9cf0 100644 --- a/src/worker/jobs/readmes.rs +++ b/src/worker/jobs/readmes.rs @@ -5,9 +5,9 @@ use crate::tasks::spawn_blocking; use crate::worker::Environment; use crates_io_markdown::text_to_html; use crates_io_worker::BackgroundJob; -use diesel_async::async_connection_wrapper::AsyncConnectionWrapper; +use diesel_async::scoped_futures::ScopedFutureExt; +use diesel_async::AsyncConnection; use std::sync::Arc; -use tokio::runtime::Handle; #[derive(Clone, Serialize, Deserialize)] pub struct RenderAndUploadReadme { @@ -46,6 +46,7 @@ impl BackgroundJob for RenderAndUploadReadme { async fn run(&self, env: Self::Context) -> anyhow::Result<()> { use crate::schema::*; use diesel::prelude::*; + use diesel_async::RunQueryDsl; info!(version_id = ?self.version_id, "Rendering README"); @@ -64,26 +65,25 @@ impl BackgroundJob for RenderAndUploadReadme { return Ok(()); } - let conn = env.deadpool.get().await?; - spawn_blocking(move || { - let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into(); - - conn.transaction(|conn| { - Version::record_readme_rendering(job.version_id, conn)?; + let mut conn = env.deadpool.get().await?; + conn.transaction(|conn| { + async move { + Version::record_readme_rendering(job.version_id, conn).await?; let (crate_name, vers): (String, String) = versions::table .find(job.version_id) .inner_join(crates::table) .select((crates::name, versions::num)) - .first(conn)?; + .first(conn) + .await?; tracing::Span::current().record("krate.name", tracing::field::display(&crate_name)); let bytes = rendered.into(); - let future = env.storage.upload_readme(&crate_name, &vers, bytes); - Handle::current().block_on(future)?; + env.storage.upload_readme(&crate_name, &vers, bytes).await?; Ok(()) - }) + } + .scope_boxed() }) .await }