Skip to content

Commit b18b564

Browse files
Carbonhellsyphar
authored andcommitted
refactor(queue): centralize definition for common priority levels
fix(queue): update query for faulty rustdoc builds to not assume build status implies anything on the rustdoc result, match on all releases of each crate rather than the latest only, and use the release_build_status table to simplify the query fix(logs): use fields for info! instead of string formatting docs(cratesfyi): clarify usage of command arguments for the new RebuildBrokenNightly command chore(tests): remove unneeded test environment config
1 parent 5fe131e commit b18b564

File tree

6 files changed

+153
-137
lines changed

6 files changed

+153
-137
lines changed

src/bin/cratesfyi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ enum QueueSubcommand {
276276
head: bool,
277277
},
278278

279-
/// Queue rebuilds for broken nightly versions of rustdoc
279+
/// Queue rebuilds for broken nightly versions of rustdoc, either for a single date (start) or a range (start inclusive, end exclusive)
280280
RebuildBrokenNightly {
281281
/// Start date of nightly builds to rebuild (inclusive)
282282
#[arg(name = "START", short = 's', long = "start")]

src/build_queue.rs

Lines changed: 125 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,21 @@ impl BuildQueueMetrics {
4040
}
4141
}
4242

43-
/// The static priority for background rebuilds.
44-
/// Used when queueing rebuilds, and when rendering them
45-
/// collapsed in the UI.
46-
/// For normal build priorities we use smaller values.
47-
pub(crate) const REBUILD_PRIORITY: i32 = 20;
48-
// TODO what value should we use here?
49-
pub(crate) const BROKEN_RUSTDOC_REBUILD_PRIORITY: i32 = 30;
43+
44+
45+
pub(crate) const PRIORITY_DEFAULT: i32 = 0;
46+
/// Used for workspaces to avoid blocking the queue (done through the cratesfyi CLI, not used in code)
47+
#[allow(dead_code)]
48+
pub(crate) const PRIORITY_DEPRIORITIZED: i32 = 1;
49+
/// Rebuilds triggered from crates.io, see issue #2442
50+
pub(crate) const PRIORITY_MANUAL_FROM_CRATES_IO: i32 = 5;
51+
/// Used for rebuilds queued through cratesfyi for crate versions failed due to a broken Rustdoc nightly version.
52+
/// Note: a broken rustdoc version does not necessarily imply a failed build.
53+
pub(crate) const PRIORITY_BROKEN_RUSTDOC: i32 = 10;
54+
/// Used by the synchronize cratesfyi command when queueing builds that are in the crates.io index but not in the database.
55+
pub(crate) const PRIORITY_CONSISTENCY_CHECK: i32 = 15;
56+
/// The static priority for background rebuilds, used when queueing rebuilds, and when rendering them collapsed in the UI.
57+
pub(crate) const PRIORITY_CONTINUOUS: i32 = 20;
5058

5159
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize)]
5260
pub(crate) struct QueuedCrate {
@@ -726,7 +734,7 @@ pub async fn queue_rebuilds(
726734
.pending_count_by_priority()
727735
.await?
728736
.iter()
729-
.filter_map(|(priority, count)| (*priority >= REBUILD_PRIORITY).then_some(count))
737+
.filter_map(|(priority, count)| (*priority >= PRIORITY_CONTINUOUS).then_some(count))
730738
.sum();
731739

732740
let rebuilds_to_queue = config
@@ -770,7 +778,7 @@ pub async fn queue_rebuilds(
770778
{
771779
info!("queueing rebuild for {} {}...", &row.name, &row.version);
772780
build_queue
773-
.add_crate(&row.name, &row.version, REBUILD_PRIORITY, None)
781+
.add_crate(&row.name, &row.version, PRIORITY_CONTINUOUS, None)
774782
.await?;
775783
}
776784
}
@@ -799,18 +807,16 @@ SELECT c.name,
799807
r.version AS "version: Version"
800808
FROM crates AS c
801809
JOIN releases AS r
802-
ON c.latest_version_id = r.id
803-
AND r.rustdoc_status = TRUE
804-
JOIN LATERAL (
805-
SELECT b.id,
806-
b.build_status,
807-
b.rustc_nightly_date,
808-
COALESCE(b.build_finished, b.build_started) AS last_build_attempt
809-
FROM builds AS b
810-
WHERE b.rid = r.id
811-
ORDER BY last_build_attempt DESC
812-
LIMIT 1
813-
) AS b ON b.build_status = 'failure' AND b.rustc_nightly_date >= $1 AND b.rustc_nightly_date < $2
810+
ON c.id = r.crate_id
811+
JOIN release_build_status AS rbs
812+
ON rbs.rid = r.id
813+
AND rbs.build_status != 'in_progress'
814+
JOIN builds AS b
815+
ON b.rid = r.id
816+
AND b.build_finished = rbs.last_build_time
817+
AND b.rustc_nightly_date >= $1
818+
AND b.rustc_nightly_date < $2
819+
814820
815821
"#, start_nightly_date, end_nightly_date
816822
)
@@ -826,16 +832,13 @@ FROM crates AS c
826832
{
827833
results_count += 1;
828834
info!(
829-
"queueing rebuild for {} {} (priority {})...",
830-
&row.name, &row.version, BROKEN_RUSTDOC_REBUILD_PRIORITY
835+
name=%row.name,
836+
version=%row.version,
837+
priority=PRIORITY_BROKEN_RUSTDOC,
838+
"queueing rebuild"
831839
);
832840
build_queue
833-
.add_crate(
834-
&row.name,
835-
&row.version,
836-
BROKEN_RUSTDOC_REBUILD_PRIORITY,
837-
None,
838-
)
841+
.add_crate(&row.name, &row.version, PRIORITY_BROKEN_RUSTDOC, None)
839842
.await?;
840843
}
841844
}
@@ -881,35 +884,41 @@ mod tests {
881884
assert_eq!(queue.len(), 1);
882885
assert_eq!(queue[0].name, "foo");
883886
assert_eq!(queue[0].version, V1);
884-
assert_eq!(queue[0].priority, REBUILD_PRIORITY);
887+
assert_eq!(queue[0].priority, PRIORITY_CONTINUOUS);
885888

886889
Ok(())
887890
}
888891

889-
/// Verifies whether a rebuild is queued for a crate that previously failed with a nightly version of rustdoc.
892+
/// Verifies whether a rebuild is queued for all releases with the latest build performed with a specific nightly version of rustdoc
890893
#[tokio::test(flavor = "multi_thread")]
891894
async fn test_rebuild_broken_rustdoc_specific_date_simple() -> Result<()> {
892-
let env = TestEnvironment::with_config(
893-
TestEnvironment::base_config()
894-
.max_queued_rebuilds(Some(100))
895-
.build()?,
896-
)
897-
.await?;
895+
let env = TestEnvironment::new().await?;
898896

899-
for i in 1..5 {
900-
let nightly_date = NaiveDate::from_ymd_opt(2020, 10, i).unwrap();
897+
// Matrix of test builds (crate name, nightly date, version)
898+
let build_matrix = [
899+
// Should be skipped since this is not the latest build for this release
900+
("foo1", NaiveDate::from_ymd_opt(2020, 10, 1).unwrap(), V1),
901+
// All those should match
902+
("foo1", NaiveDate::from_ymd_opt(2020, 10, 2).unwrap(), V1),
903+
("foo1", NaiveDate::from_ymd_opt(2020, 10, 2).unwrap(), V2),
904+
("foo2", NaiveDate::from_ymd_opt(2020, 10, 2).unwrap(), V1),
905+
// Should be skipped since the nightly doesn't match
906+
("foo2", NaiveDate::from_ymd_opt(2020, 10, 3).unwrap(), V2),
907+
];
908+
for build in build_matrix.into_iter() {
909+
let (crate_name, nightly, version) = build;
901910
env.fake_release()
902911
.await
903-
.name(&format!("foo{}", i))
904-
.version(V1)
912+
.name(crate_name)
913+
.version(version)
905914
.builds(vec![
906915
FakeBuild::default()
907916
.rustc_version(
908917
format!(
909918
"rustc 1.84.0-nightly (e7c0d2750 {})",
910-
nightly_date.format("%Y-%m-%d")
919+
nightly.format("%Y-%m-%d")
911920
)
912-
.as_str(),
921+
.as_str(),
913922
)
914923
.build_status(BuildStatus::Failure),
915924
])
@@ -924,60 +933,60 @@ mod tests {
924933
queue_rebuilds_faulty_rustdoc(
925934
&mut conn,
926935
build_queue,
927-
&NaiveDate::from_ymd_opt(2020, 10, 3).unwrap(),
936+
&NaiveDate::from_ymd_opt(2020, 10, 2).unwrap(),
928937
&None,
929938
)
930939
.await?;
931940

932941
let queue = build_queue.queued_crates().await?;
933-
assert_eq!(queue.len(), 1);
934-
assert_eq!(queue[0].name, "foo3");
942+
assert_eq!(queue.len(), 3);
943+
assert_eq!(queue[0].name, "foo1");
935944
assert_eq!(queue[0].version, V1);
936-
assert_eq!(queue[0].priority, BROKEN_RUSTDOC_REBUILD_PRIORITY);
945+
assert_eq!(queue[0].priority, PRIORITY_BROKEN_RUSTDOC);
946+
assert_eq!(queue[1].name, "foo1");
947+
assert_eq!(queue[1].version, V2);
948+
assert_eq!(queue[1].priority, PRIORITY_BROKEN_RUSTDOC);
949+
assert_eq!(queue[2].name, "foo2");
950+
assert_eq!(queue[2].version, V1);
951+
assert_eq!(queue[2].priority, PRIORITY_BROKEN_RUSTDOC);
937952

938953
Ok(())
939954
}
940955

941-
/// Verified whether a rebuild is NOT queued since the latest build for the specific crate is marked as successful.
956+
/// Verifies whether a rebuild is NOT queued for any crate if the nightly specified doesn't match any latest build of any release
942957
#[tokio::test(flavor = "multi_thread")]
943958
async fn test_rebuild_broken_rustdoc_specific_date_skipped() -> Result<()> {
944-
let env = TestEnvironment::with_config(
945-
TestEnvironment::base_config()
946-
.max_queued_rebuilds(Some(100))
947-
.build()?,
948-
)
949-
.await?;
959+
let env = TestEnvironment::new().await?;
950960

951-
env.fake_release()
952-
.await
953-
.name("foo")
954-
.version(V1)
955-
.builds(vec![
956-
FakeBuild::default()
957-
.rustc_version(
958-
format!(
959-
"rustc 1.84.0-nightly (e7c0d2750 {})",
960-
NaiveDate::from_ymd_opt(2020, 10, 1)
961-
.unwrap()
962-
.format("%Y-%m-%d")
963-
)
964-
.as_str(),
965-
)
966-
.build_status(BuildStatus::Failure),
967-
FakeBuild::default()
968-
.rustc_version(
969-
format!(
970-
"rustc 1.84.0-nightly (e7c0d2750 {})",
971-
NaiveDate::from_ymd_opt(2020, 10, 1)
972-
.unwrap()
973-
.format("%Y-%m-%d")
961+
// Matrix of test builds (crate name, nightly date, version)
962+
let build_matrix = [
963+
// Should be skipped since this is not the latest build for this release even if the nightly matches
964+
("foo1", NaiveDate::from_ymd_opt(2020, 10, 3).unwrap(), V1),
965+
// Should be skipped since the nightly doesn't match
966+
("foo1", NaiveDate::from_ymd_opt(2020, 10, 2).unwrap(), V1),
967+
// Should be skipped since the nightly doesn't match
968+
("foo2", NaiveDate::from_ymd_opt(2020, 10, 4).unwrap(), V1),
969+
];
970+
for build in build_matrix.into_iter() {
971+
let (crate_name, nightly, version) = build;
972+
env.fake_release()
973+
.await
974+
.name(crate_name)
975+
.version(version)
976+
.builds(vec![
977+
FakeBuild::default()
978+
.rustc_version(
979+
format!(
980+
"rustc 1.84.0-nightly (e7c0d2750 {})",
981+
nightly.format("%Y-%m-%d")
982+
)
983+
.as_str(),
974984
)
975-
.as_str(),
976-
)
977-
.build_status(BuildStatus::Success),
978-
])
979-
.create()
980-
.await?;
985+
.build_status(BuildStatus::Failure),
986+
])
987+
.create()
988+
.await?;
989+
}
981990

982991
let build_queue = env.async_build_queue();
983992
assert!(build_queue.queued_crates().await?.is_empty());
@@ -986,7 +995,7 @@ mod tests {
986995
queue_rebuilds_faulty_rustdoc(
987996
&mut conn,
988997
build_queue,
989-
&NaiveDate::from_ymd_opt(2020, 10, 1).unwrap(),
998+
&NaiveDate::from_ymd_opt(2020, 10, 3).unwrap(),
990999
&None,
9911000
)
9921001
.await?;
@@ -997,29 +1006,36 @@ mod tests {
9971006
Ok(())
9981007
}
9991008

1009+
/// Verifies whether a rebuild is queued for all releases with the latest build performed with a nightly version between two dates
10001010
#[tokio::test(flavor = "multi_thread")]
10011011
async fn test_rebuild_broken_rustdoc_date_range() -> Result<()> {
1002-
let env = TestEnvironment::with_config(
1003-
TestEnvironment::base_config()
1004-
.max_queued_rebuilds(Some(100))
1005-
.build()?,
1006-
)
1007-
.await?;
1012+
let env = TestEnvironment::new().await?;
10081013

1009-
for i in 1..6 {
1010-
let nightly_date = NaiveDate::from_ymd_opt(2020, 10, i).unwrap();
1014+
// Matrix of test builds (crate name, nightly date, version)
1015+
let build_matrix = [
1016+
// Should be skipped since this is not the latest build for this release
1017+
("foo1", NaiveDate::from_ymd_opt(2020, 10, 1).unwrap(), V1),
1018+
// All those should match
1019+
("foo1", NaiveDate::from_ymd_opt(2020, 10, 2).unwrap(), V1),
1020+
("foo1", NaiveDate::from_ymd_opt(2020, 10, 3).unwrap(), V2),
1021+
("foo2", NaiveDate::from_ymd_opt(2020, 10, 4).unwrap(), V1),
1022+
// Should be skipped since the nightly doesn't match (end date is exclusive)
1023+
("foo2", NaiveDate::from_ymd_opt(2020, 10, 5).unwrap(), V2),
1024+
];
1025+
for build in build_matrix.into_iter() {
1026+
let (crate_name, nightly, version) = build;
10111027
env.fake_release()
10121028
.await
1013-
.name(&format!("foo{}", i))
1014-
.version(V1)
1029+
.name(crate_name)
1030+
.version(version)
10151031
.builds(vec![
10161032
FakeBuild::default()
10171033
.rustc_version(
10181034
format!(
10191035
"rustc 1.84.0-nightly (e7c0d2750 {})",
1020-
nightly_date.format("%Y-%m-%d")
1036+
nightly.format("%Y-%m-%d")
10211037
)
1022-
.as_str(),
1038+
.as_str(),
10231039
)
10241040
.build_status(BuildStatus::Failure),
10251041
])
@@ -1034,19 +1050,22 @@ mod tests {
10341050
queue_rebuilds_faulty_rustdoc(
10351051
&mut conn,
10361052
build_queue,
1037-
&NaiveDate::from_ymd_opt(2020, 10, 3).unwrap(),
1053+
&NaiveDate::from_ymd_opt(2020, 10, 2).unwrap(),
10381054
&NaiveDate::from_ymd_opt(2020, 10, 5),
10391055
)
10401056
.await?;
10411057

10421058
let queue = build_queue.queued_crates().await?;
1043-
assert_eq!(queue.len(), 2);
1044-
assert_eq!(queue[0].name, "foo3");
1059+
assert_eq!(queue.len(), 3);
1060+
assert_eq!(queue[0].name, "foo1");
10451061
assert_eq!(queue[0].version, V1);
1046-
assert_eq!(queue[0].priority, BROKEN_RUSTDOC_REBUILD_PRIORITY);
1047-
assert_eq!(queue[1].name, "foo4");
1062+
assert_eq!(queue[0].priority, PRIORITY_BROKEN_RUSTDOC);
1063+
assert_eq!(queue[1].name, "foo1");
1064+
assert_eq!(queue[1].version, V2);
1065+
assert_eq!(queue[1].priority, PRIORITY_BROKEN_RUSTDOC);
1066+
assert_eq!(queue[1].name, "foo2");
10481067
assert_eq!(queue[1].version, V1);
1049-
assert_eq!(queue[1].priority, BROKEN_RUSTDOC_REBUILD_PRIORITY);
1068+
assert_eq!(queue[1].priority, PRIORITY_BROKEN_RUSTDOC);
10501069

10511070
Ok(())
10521071
}
@@ -1062,10 +1081,10 @@ mod tests {
10621081

10631082
let build_queue = env.async_build_queue();
10641083
build_queue
1065-
.add_crate("foo1", &V1, REBUILD_PRIORITY, None)
1084+
.add_crate("foo1", &V1, PRIORITY_CONTINUOUS, None)
10661085
.await?;
10671086
build_queue
1068-
.add_crate("foo2", &V1, REBUILD_PRIORITY, None)
1087+
.add_crate("foo2", &V1, PRIORITY_CONTINUOUS, None)
10691088
.await?;
10701089

10711090
let mut conn = env.async_db().async_conn().await;
@@ -1104,10 +1123,10 @@ mod tests {
11041123

11051124
let build_queue = env.async_build_queue();
11061125
build_queue
1107-
.add_crate("foo1", &V1, REBUILD_PRIORITY, None)
1126+
.add_crate("foo1", &V1, PRIORITY_CONTINUOUS, None)
11081127
.await?;
11091128
build_queue
1110-
.add_crate("foo2", &V1, REBUILD_PRIORITY, None)
1129+
.add_crate("foo2", &V1, PRIORITY_CONTINUOUS, None)
11111130
.await?;
11121131

11131132
env.fake_release()

0 commit comments

Comments
 (0)