Skip to content

Commit 81531a5

Browse files
committed
Auto merge of #4120 - Turbo87:yank-db, r=Turbo87
worker::git: Move database update out of `yank()` job When publishing, we also save the new version (and crate) directly in the database, so we should be able to do the same when yanking/unyanking, and avoid potentially returning incorrect data right after the request and before the background job has finished.
2 parents 35d7c23 + 2331392 commit 81531a5

File tree

2 files changed

+36
-46
lines changed

2 files changed

+36
-46
lines changed

src/controllers/version/yank.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use super::{extract_crate_name_and_semver, version_and_crate};
66
use crate::controllers::cargo_prelude::*;
77
use crate::models::Rights;
88
use crate::models::{insert_version_owner_action, VersionAction};
9+
use crate::schema::versions;
910
use crate::worker;
1011

1112
/// Handles the `DELETE /crates/:crate_id/:version/yank` route.
@@ -42,6 +43,16 @@ fn modify_yank(req: &mut dyn RequestExt, yanked: bool) -> EndpointResult {
4243
if user.rights(req.app(), &owners)? < Rights::Publish {
4344
return Err(cargo_err("must already be an owner to yank or unyank"));
4445
}
46+
47+
if version.yanked == yanked {
48+
// The crate is already in the state requested, nothing to do
49+
return ok_true();
50+
}
51+
52+
diesel::update(&version)
53+
.set(versions::yanked.eq(yanked))
54+
.execute(&*conn)?;
55+
4556
let action = if yanked {
4657
VersionAction::Yank
4758
} else {

src/worker/git.rs

Lines changed: 25 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use crate::background_jobs::Environment;
22
use crate::git::{Crate, Credentials};
33
use crate::models::Version;
4-
use crate::schema::versions;
54
use chrono::Utc;
65
use std::fs::{self, OpenOptions};
76
use std::io::prelude::*;
@@ -31,60 +30,40 @@ pub fn add_crate(env: &Environment, krate: Crate) -> Result<(), PerformError> {
3130
/// push the changes.
3231
#[swirl::background_job]
3332
pub fn yank(
34-
conn: &PgConnection,
3533
env: &Environment,
3634
krate: String,
3735
version: Version,
3836
yanked: bool,
3937
) -> Result<(), PerformError> {
40-
use diesel::prelude::*;
41-
4238
let repo = env.lock_index()?;
4339
let dst = repo.index_file(&krate);
4440

45-
conn.transaction(|| {
46-
let yanked_in_db: bool = versions::table
47-
.find(version.id)
48-
.select(versions::yanked)
49-
.for_update()
50-
.first(&*conn)?;
51-
52-
if yanked_in_db == yanked {
53-
// The crate is alread in the state requested, nothing to do
54-
return Ok(());
55-
}
41+
let prev = fs::read_to_string(&dst)?;
42+
let new = prev
43+
.lines()
44+
.map(|line| {
45+
let mut git_crate = serde_json::from_str::<Crate>(line)
46+
.map_err(|_| format!("couldn't decode: `{}`", line))?;
47+
if git_crate.name != krate || git_crate.vers != version.num {
48+
return Ok(line.to_string());
49+
}
50+
git_crate.yanked = Some(yanked);
51+
Ok(serde_json::to_string(&git_crate)?)
52+
})
53+
.collect::<Result<Vec<_>, PerformError>>();
54+
let new = new?.join("\n") + "\n";
55+
fs::write(&dst, new.as_bytes())?;
56+
57+
let message: String = format!(
58+
"{} crate `{}#{}`",
59+
if yanked { "Yanking" } else { "Unyanking" },
60+
krate,
61+
version.num
62+
);
63+
64+
repo.commit_and_push(&message, &repo.relative_index_file(&krate))?;
5665

57-
let prev = fs::read_to_string(&dst)?;
58-
let new = prev
59-
.lines()
60-
.map(|line| {
61-
let mut git_crate = serde_json::from_str::<Crate>(line)
62-
.map_err(|_| format!("couldn't decode: `{}`", line))?;
63-
if git_crate.name != krate || git_crate.vers != version.num {
64-
return Ok(line.to_string());
65-
}
66-
git_crate.yanked = Some(yanked);
67-
Ok(serde_json::to_string(&git_crate)?)
68-
})
69-
.collect::<Result<Vec<_>, PerformError>>();
70-
let new = new?.join("\n") + "\n";
71-
fs::write(&dst, new.as_bytes())?;
72-
73-
let message: String = format!(
74-
"{} crate `{}#{}`",
75-
if yanked { "Yanking" } else { "Unyanking" },
76-
krate,
77-
version.num
78-
);
79-
80-
repo.commit_and_push(&message, &repo.relative_index_file(&krate))?;
81-
82-
diesel::update(&version)
83-
.set(versions::yanked.eq(yanked))
84-
.execute(&*conn)?;
85-
86-
Ok(())
87-
})
66+
Ok(())
8867
}
8968

9069
/// Collapse the index into a single commit, archiving the current history in a snapshot branch.

0 commit comments

Comments
 (0)