Skip to content

Commit 71a2842

Browse files
committed
admin/delete_crate: Extract DeleteCrateFromStorage background job
This background job can later be reused to implement https://rust-lang.github.io/rfcs/3660-crates-io-crate-deletions.html
1 parent 3c970a1 commit 71a2842

File tree

4 files changed

+53
-22
lines changed

4 files changed

+53
-22
lines changed

src/admin/delete_crate.rs

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::schema::{crate_owners, teams, users};
2-
use crate::storage::{FeedId, Storage};
32
use crate::worker::jobs;
43
use crate::{admin::dialoguer, db, schema::crates};
54
use anyhow::Context;
5+
use crates_io_worker::BackgroundJob;
66
use diesel::dsl::sql;
77
use diesel::prelude::*;
88
use diesel::sql_types::Text;
@@ -27,8 +27,6 @@ pub struct Opts {
2727
pub fn run(opts: Opts) -> anyhow::Result<()> {
2828
let conn = &mut db::oneoff_connection().context("Failed to establish database connection")?;
2929

30-
let store = Storage::from_environment();
31-
3230
let mut crate_names = opts.crate_names;
3331
crate_names.sort();
3432

@@ -73,11 +71,6 @@ pub fn run(opts: Opts) -> anyhow::Result<()> {
7371
return Ok(());
7472
}
7573

76-
let rt = tokio::runtime::Builder::new_current_thread()
77-
.enable_all()
78-
.build()
79-
.context("Failed to initialize tokio runtime")?;
80-
8174
for name in &crate_names {
8275
if let Some((id, _)) = existing_crates.get(name) {
8376
info!("{name}: Deleting crate from the database…");
@@ -93,20 +86,10 @@ pub fn run(opts: Opts) -> anyhow::Result<()> {
9386
warn!("{name}: Failed to enqueue index sync jobs: {error}");
9487
}
9588

96-
info!("{name}: Deleting crate files from S3…");
97-
if let Err(error) = rt.block_on(store.delete_all_crate_files(name)) {
98-
warn!("{name}: Failed to delete crate files from S3: {error}");
99-
}
100-
101-
info!("{name}: Deleting readme files from S3…");
102-
if let Err(error) = rt.block_on(store.delete_all_readmes(name)) {
103-
warn!("{name}: Failed to delete readme files from S3: {error}");
104-
}
105-
106-
info!("{name}: Deleting RSS feed from S3…");
107-
let feed_id = FeedId::Crate { name };
108-
if let Err(error) = rt.block_on(store.delete_feed(&feed_id)) {
109-
warn!("{name}: Failed to delete RSS feed from S3: {error}");
89+
info!("{name}: Enqueuing DeleteCrateFromStorage job…");
90+
let job = jobs::DeleteCrateFromStorage::new(name.into());
91+
if let Err(error) = job.enqueue(conn) {
92+
warn!("{name}: Failed to enqueue DeleteCrateFromStorage job: {error}");
11093
}
11194
}
11295

src/worker/jobs/delete_crate.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use crate::storage::FeedId;
2+
use crate::worker::Environment;
3+
use crates_io_worker::BackgroundJob;
4+
use std::sync::Arc;
5+
6+
/// A background job that deletes all files associated with a crate from the storage backend.
7+
#[derive(Serialize, Deserialize)]
8+
pub struct DeleteCrateFromStorage {
9+
name: String,
10+
}
11+
12+
impl DeleteCrateFromStorage {
13+
pub fn new(name: String) -> Self {
14+
Self { name }
15+
}
16+
}
17+
18+
impl BackgroundJob for DeleteCrateFromStorage {
19+
const JOB_NAME: &'static str = "delete_crate_from_storage";
20+
21+
type Context = Arc<Environment>;
22+
23+
async fn run(&self, ctx: Self::Context) -> anyhow::Result<()> {
24+
let name = &self.name;
25+
26+
info!("{name}: Deleting crate files from S3…");
27+
if let Err(error) = ctx.storage.delete_all_crate_files(name).await {
28+
warn!("{name}: Failed to delete crate files from S3: {error}");
29+
}
30+
31+
info!("{name}: Deleting readme files from S3…");
32+
if let Err(error) = ctx.storage.delete_all_readmes(name).await {
33+
warn!("{name}: Failed to delete readme files from S3: {error}");
34+
}
35+
36+
info!("{name}: Deleting RSS feed from S3…");
37+
let feed_id = FeedId::Crate { name };
38+
if let Err(error) = ctx.storage.delete_feed(&feed_id).await {
39+
warn!("{name}: Failed to delete RSS feed from S3: {error}");
40+
}
41+
42+
info!("{name}: Successfully deleted crate from S3");
43+
Ok(())
44+
}
45+
}

src/worker/jobs/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::fmt::Display;
88

99
mod archive_version_downloads;
1010
mod daily_db_maintenance;
11+
mod delete_crate;
1112
mod downloads;
1213
pub mod dump_db;
1314
mod expiry_notification;
@@ -22,6 +23,7 @@ mod update_default_version;
2223

2324
pub use self::archive_version_downloads::ArchiveVersionDownloads;
2425
pub use self::daily_db_maintenance::DailyDbMaintenance;
26+
pub use self::delete_crate::DeleteCrateFromStorage;
2527
pub use self::downloads::{
2628
CleanProcessedLogFiles, ProcessCdnLog, ProcessCdnLogQueue, UpdateDownloads,
2729
};

src/worker/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ impl RunnerExt for Runner<Arc<Environment>> {
2323
.register_job_type::<jobs::CheckTyposquat>()
2424
.register_job_type::<jobs::CleanProcessedLogFiles>()
2525
.register_job_type::<jobs::DailyDbMaintenance>()
26+
.register_job_type::<jobs::DeleteCrateFromStorage>()
2627
.register_job_type::<jobs::DumpDb>()
2728
.register_job_type::<jobs::IndexVersionDownloadsArchive>()
2829
.register_job_type::<jobs::NormalizeIndex>()

0 commit comments

Comments
 (0)