Skip to content

Commit 6dc97be

Browse files
authored
Merge pull request #9617 from Turbo87/async-delete-crate
admin/delete_crate: Reduce `spawn_blocking()` usage
2 parents 1ee72eb + 0b6b12e commit 6dc97be

File tree

1 file changed

+56
-44
lines changed

1 file changed

+56
-44
lines changed

src/admin/delete_crate.rs

Lines changed: 56 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ use crate::{admin::dialoguer, db, schema::crates};
55
use anyhow::Context;
66
use crates_io_worker::BackgroundJob;
77
use diesel::dsl::sql;
8-
use diesel::prelude::*;
98
use diesel::sql_types::Text;
9+
use diesel::{ExpressionMethods, JoinOnDsl, QueryDsl};
10+
use diesel_async::async_connection_wrapper::AsyncConnectionWrapper;
1011
use std::collections::HashMap;
1112

1213
#[derive(clap::Parser, Debug)]
@@ -26,53 +27,64 @@ pub struct Opts {
2627
}
2728

2829
pub async fn run(opts: Opts) -> anyhow::Result<()> {
29-
spawn_blocking(move || {
30-
let conn =
31-
&mut db::oneoff_connection().context("Failed to establish database connection")?;
32-
33-
let mut crate_names = opts.crate_names;
34-
crate_names.sort();
35-
36-
let query_result = crates::table
37-
.select((
38-
crates::name,
39-
crates::id,
40-
sql::<Text>(
41-
"CASE WHEN crate_owners.owner_kind = 1 THEN teams.login ELSE users.gh_login END",
42-
),
43-
))
44-
.left_join(crate_owners::table.on(crate_owners::crate_id.eq(crates::id)))
45-
.left_join(teams::table.on(teams::id.eq(crate_owners::owner_id)))
46-
.left_join(users::table.on(users::id.eq(crate_owners::owner_id)))
47-
.filter(crates::name.eq_any(&crate_names))
48-
.load::<(String, i32, String)>(conn)
49-
.context("Failed to look up crate name from the database")?;
50-
51-
let mut existing_crates: HashMap<String, (i32, Vec<String>)> = HashMap::new();
52-
for (name, id, login) in query_result {
53-
let entry = existing_crates
54-
.entry(name)
55-
.or_insert_with(|| (id, Vec::new()));
56-
57-
entry.1.push(login);
58-
}
30+
let mut conn = db::oneoff_async_connection()
31+
.await
32+
.context("Failed to establish database connection")?;
5933

60-
println!("Deleting the following crates:");
61-
println!();
62-
for name in &crate_names {
63-
match existing_crates.get(name) {
64-
Some((id, owners)) => {
65-
let owners = owners.join(", ");
66-
println!(" - {name} (id={id}, owners={owners})");
67-
}
68-
None => println!(" - {name} (⚠️ crate not found)"),
34+
let mut crate_names = opts.crate_names;
35+
crate_names.sort();
36+
37+
let query_result = {
38+
use diesel_async::RunQueryDsl;
39+
40+
crates::table
41+
.select((
42+
crates::name,
43+
crates::id,
44+
sql::<Text>(
45+
"CASE WHEN crate_owners.owner_kind = 1 THEN teams.login ELSE users.gh_login END",
46+
),
47+
))
48+
.left_join(crate_owners::table.on(crate_owners::crate_id.eq(crates::id)))
49+
.left_join(teams::table.on(teams::id.eq(crate_owners::owner_id)))
50+
.left_join(users::table.on(users::id.eq(crate_owners::owner_id)))
51+
.filter(crates::name.eq_any(&crate_names))
52+
.load::<(String, i32, String)>(&mut conn).await
53+
.context("Failed to look up crate name from the database")
54+
}?;
55+
56+
let mut existing_crates: HashMap<String, (i32, Vec<String>)> = HashMap::new();
57+
for (name, id, login) in query_result {
58+
let entry = existing_crates
59+
.entry(name)
60+
.or_insert_with(|| (id, Vec::new()));
61+
62+
entry.1.push(login);
63+
}
64+
65+
println!("Deleting the following crates:");
66+
println!();
67+
for name in &crate_names {
68+
match existing_crates.get(name) {
69+
Some((id, owners)) => {
70+
let owners = owners.join(", ");
71+
println!(" - {name} (id={id}, owners={owners})");
6972
}
73+
None => println!(" - {name} (⚠️ crate not found)"),
7074
}
71-
println!();
75+
}
76+
println!();
7277

73-
if !opts.yes && !dialoguer::confirm("Do you want to permanently delete these crates?")? {
74-
return Ok(());
75-
}
78+
if !opts.yes
79+
&& !dialoguer::async_confirm("Do you want to permanently delete these crates?").await?
80+
{
81+
return Ok(());
82+
}
83+
84+
spawn_blocking(move || {
85+
use diesel::RunQueryDsl;
86+
87+
let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into();
7688

7789
for name in &crate_names {
7890
if let Some((id, _)) = existing_crates.get(name) {

0 commit comments

Comments
 (0)